[PATCH] Fix bug in llvm::DemoteRegToStack
Nick Lewycky
nicholas at mxc.ca
Wed Jan 7 22:20:52 PST 2015
- lib/Transforms/Utils/DemoteRegToStack.cpp
+++ lib/Transforms/Utils/DemoteRegToStack.cpp
@@ -21,6 +21,7 @@
/// alloca. This allows the CFG to be changed around without fear of
/// invalidating the SSA information for the value. It returns the
pointer to
/// the alloca inserted to create a stack slot for I.
+
AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
Instruction *AllocaPoint) {
if (I.use_empty()) {
Remove the extra blank line, this comment is attached to this function.
+ StoreInst *Store = new StoreInst(&I, Slot, InsertPt);
+
+ // Change all of the users of the instruction, except the Store we've
just
+ // inserted, to read from the stack slot.
+ SmallVector<User*, 4> UsersOfI(I.users());
+
+ for (User *U : UsersOfI) {
+ if (PHINode *PN = dyn_cast<PHINode>(U)) {
Can you avoid the extra copy? What if you create the store now, but
don't insert it yet? (I think InsertPt can't be one of the users, correct?)
While we're here:
for (; isa<PHINode>(InsertPt) || isa<LandingPadInst>(InsertPt);
++InsertPt)
/* empty */; // Don't insert before PHI nodes or landingpad instrs.
This is redundant with getFirstInsertionPt. Can this be hoisted up to
the only place that sets InsertPt without using getFirstInsertionPt?
Nick
Akira Hatanaka wrote:
> In the following example, when DemoteRegToStack demotes %call.i.i.i14.i.i, it firsts scans all the uses of %call.i.i.i14.i.i and inserts load instructions before all its users. Since %0 is a phi instruction, a load instruction is inserted in the predecessor block, which is the entry basic block. Then it inserts a store instruction to save the value it is demoting to the stack. In this case, %call.i.i.i14.i.i is an invoke, so it creates a basic block that splits the critical edge (entry-do.body.i.i.i), and inserts the store there. This is incorrect because the store instruction should be executed before the load instruction.
>
> define void @_Z4foo1c(i8 signext %a) {
> entry:
>
> ...
> %call.i.i.i14.i.i = invoke noalias i8* @_Znwm(i32 1024)
> to label %do.body.i.i.i unwind label %lpad.body
>
> do.body.i.i.i: ; preds = %entry, %_ZNSt3__116allocator_traitsINS_9allocatorIcEEE9constructIccEEvRS2_PT_RKT0_.exit.i.i.i
>
> %0 = phi i8* [ %incdec.ptr.i.i.i, %_ZNSt3__116allocator_traitsINS_9allocatorIcEEE9constructIccEEvRS2_PT_RKT0_.exit.i.i.i ], [ %call.i.i.i14.i.i, %entry ]
> ...
>
> The IR after SjLjEHPrepare pass looks like this:
>
> define void @_Z4foo1c(i8 signext %a) {
> entry:
>
> %call.i.i.i14.i.i.reg2mem = alloca i8*
> ...
> %call.i.i.i14.i.i.reload = load volatile i8** %call.i.i.i14.i.i.reg2mem
> ...
> %call.i.i.i14.i.i = invoke noalias i8* @_Znwm(i32 1024)
> to label %entry.do.body.i.i.i_crit_edge unwind label %lpad.body
>
> entry.do.body.i.i.i_crit_edge: ; preds = %entry
>
> store i8* %call.i.i.i14.i.i, i8** %call.i.i.i14.i.i.reg2mem
> br label %do.body.i.i.i
>
> do.body.i.i.i: ; preds = %entry.do.body.i.i.i_crit_edge, %_ZNSt3__116allocator_traitsINS_9allocatorIcEEE9constructIccEEvRS2_PT_RKT0_.exit.i.i.i
>
> %3 = phi i8* [ %incdec.ptr.i.i.i, %_ZNSt3__116allocator_traitsINS_9allocatorIcEEE9constructIccEEvRS2_PT_RKT0_.exit.i.i.i ], [ %call.i.i.i14.i.i.reload, %entry.do.body.i.i.i_crit_edge ]
>
> This patch fixes the bug by changing llvm::DemoteRegToStack to insert the store instruction and create basic blocks that split critical edges first, and then insert the instructions to reload the value.
>
> http://reviews.llvm.org/D6729
>
> Files:
>
> lib/Transforms/Utils/DemoteRegToStack.cpp
> test/CodeGen/ARM/sjlj-prepare-critical-edge.ll
>
> EMAIL PREFERENCES
>
> http://reviews.llvm.org/settings/panel/emailpreferences/
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
http://reviews.llvm.org/D6729
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the llvm-commits
mailing list