-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[flang] Insert stacksave/stackrestore when alloca are present in loops #95173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ | |
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "flang/Optimizer/Builder/FIRBuilder.h" | ||
#include "flang/Optimizer/Builder/LowLevelIntrinsics.h" | ||
#include "flang/Optimizer/Dialect/FIRDialect.h" | ||
#include "flang/Optimizer/Dialect/FIROps.h" | ||
#include "flang/Optimizer/Dialect/FIROpsSupport.h" | ||
|
@@ -51,6 +53,7 @@ class CfgLoopConv : public mlir::OpRewritePattern<fir::DoLoopOp> { | |
matchAndRewrite(DoLoopOp loop, | ||
mlir::PatternRewriter &rewriter) const override { | ||
auto loc = loop.getLoc(); | ||
bool hasAllocas = !loop.getBody()->getOps<fir::AllocaOp>().empty(); | ||
mlir::arith::IntegerOverflowFlags flags{}; | ||
if (setNSW) | ||
flags = bitEnumSet(flags, mlir::arith::IntegerOverflowFlags::nsw); | ||
|
@@ -72,6 +75,22 @@ class CfgLoopConv : public mlir::OpRewritePattern<fir::DoLoopOp> { | |
rewriter.splitBlock(conditionalBlock, conditionalBlock->begin()); | ||
auto *lastBlock = &loop.getRegion().back(); | ||
|
||
// Insert stacksave/stackrestore if there is fir.alloca operation in the | ||
// loop. | ||
if (hasAllocas) { | ||
auto mod = loop.getOperation()->getParentOfType<mlir::ModuleOp>(); | ||
fir::FirOpBuilder builder(rewriter, mod); | ||
builder.setInsertionPointToStart(firstBlock); | ||
mlir::func::FuncOp stackSave = fir::factory::getLlvmStackSave(builder); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to require making the pass a module pass. This is quite unfortunate. We can try to use LLVM dialect Would that be possible to insert stacksave/stackrestore calls during There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah if we can avoid that it would probably be better.
Yes we can be then we would miss other case (if any) of fir.alloca with dynamic size in loops. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are you sure? It seems the ops do not define any side effect interface, which means they can have any side effects and cannot be moved by a generic pass. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, Jean. |
||
mlir::func::FuncOp stackRestore = | ||
fir::factory::getLlvmStackRestore(builder); | ||
mlir::Value stackPtr = | ||
builder.create<fir::CallOp>(loc, stackSave).getResult(0); | ||
auto *terminator = lastBlock->getTerminator(); | ||
builder.setInsertionPoint(terminator); | ||
builder.create<fir::CallOp>(loc, stackRestore, stackPtr); | ||
} | ||
|
||
// Move the blocks from the DoLoopOp between initBlock and endBlock | ||
rewriter.inlineRegionBefore(loop.getRegion(), endBlock); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also note that @VijayKandiah is going to make changes in the code-gen to hoist constant-sized allocas to an entry block, so stacksave/stackrestore might be avoided in such cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This should be refined to count only dyn-sized alloca.