[llvm-commits] [llvm] r168930 - in /llvm/trunk: lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/ARM/crash.ll

Duncan Sands baldrick at free.fr
Thu Nov 29 12:28:25 PST 2012


Hi Bill,

On 29/11/12 20:38, Bill Wendling wrote:
> Author: void
> Date: Thu Nov 29 13:38:06 2012
> New Revision: 168930
>
> URL: http://llvm.org/viewvc/llvm-project?rev=168930&view=rev
> Log:
> Handle the situation where CodeGenPrepare removes a reference to a BB that has
> the last invoke instruction in the function. This also removes the last landing
> pad in an function. This is fine, but with SjLj EH code, we've already placed a
> bunch of code in the 'entry' block, which expects the landing pad to stick
> around.
>
> When we get to the situation where CGP has removed the last landing pad, go
> ahead and nuke the SjLj instructions from the 'entry' block.

how do you know that the sjlj logic added this code?  Mightn't the user have
placed calls to these guys themselves, eg by writing some IR by hand?  In which
case they might be upset if you zap their code!  Maybe the sjlj inserting pass
should run after codegenprepare, not before.

At this point I should confess that I don't understand why codegenprepare is
deleting dead basic blocks at all.  Shouldn't the IR optimizers have gotten
them already?

Ciao, Duncan.

> <rdar://problem/12721258>
>
> Modified:
>      llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
>      llvm/trunk/test/CodeGen/ARM/crash.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=168930&r1=168929&r2=168930&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Thu Nov 29 13:38:06 2012
> @@ -22,6 +22,7 @@
>   #include "llvm/InlineAsm.h"
>   #include "llvm/Instructions.h"
>   #include "llvm/IntrinsicInst.h"
> +#include "llvm/Module.h"
>   #include "llvm/Pass.h"
>   #include "llvm/ADT/DenseMap.h"
>   #include "llvm/ADT/SmallSet.h"
> @@ -183,8 +184,12 @@
>     if (!DisableBranchOpts) {
>       MadeChange = false;
>       SmallPtrSet<BasicBlock*, 8> WorkList;
> +    SmallPtrSet<BasicBlock*, 8> LPadList;
> +    SmallVector<BasicBlock*, 8> ReturnList;
>       for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
>         SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
> +      if (BB->isLandingPad()) LPadList.insert(BB);
> +      if (isa<ReturnInst>(BB->getTerminator())) ReturnList.push_back(BB);
>         MadeChange |= ConstantFoldTerminator(BB, true);
>         if (!MadeChange) continue;
>
> @@ -195,9 +200,11 @@
>       }
>
>       // Delete the dead blocks and any of their dead successors.
> +    bool HadLPads = !LPadList.empty();
>       while (!WorkList.empty()) {
>         BasicBlock *BB = *WorkList.begin();
>         WorkList.erase(BB);
> +      LPadList.erase(BB);
>         SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
>
>         DeleteDeadBlock(BB);
> @@ -208,6 +215,74 @@
>             WorkList.insert(*II);
>       }
>
> +    if (HadLPads && LPadList.empty()) {
> +      // All of the landing pads were removed. Get rid of the SjLj EH context
> +      // code.
> +      Module *M = F.getParent();
> +
> +      // These functions must exist if we have SjLj EH code to clean up.
> +      Constant *RegisterFn = M->getFunction("_Unwind_SjLj_Register");
> +      Constant *UnregisterFn = M->getFunction("_Unwind_SjLj_Unregister");
> +
> +      if (RegisterFn) {
> +        Constant *LSDAAddrFn =
> +          Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_lsda);
> +        Constant *FrameAddrFn =
> +          Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
> +        Constant *StackAddrFn =
> +          Intrinsic::getDeclaration(M, Intrinsic::stacksave);
> +        Constant *BuiltinSetjmpFn =
> +          Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_setjmp);
> +        Constant *FuncCtxFn =
> +          Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_functioncontext);
> +
> +        BasicBlock &Entry = F.getEntryBlock();
> +        SmallVector<Instruction*, 8> DeadInsts;
> +        for (BasicBlock::iterator I = Entry.begin(), E = Entry.end();
> +             I != E; ++I) {
> +          if (CallInst *CI = dyn_cast<CallInst>(I)) {
> +            Value *Callee = CI->getCalledValue();
> +            bool IsDead = true;
> +            if (Callee != LSDAAddrFn && Callee != FrameAddrFn &&
> +                Callee != StackAddrFn && Callee != BuiltinSetjmpFn &&
> +                Callee != FuncCtxFn && Callee != RegisterFn)
> +              IsDead = false;
> +
> +            if (IsDead) {
> +              Type *Ty = CI->getType();
> +              if (!Ty->isVoidTy())
> +                CI->replaceAllUsesWith(UndefValue::get(Ty));
> +              DeadInsts.push_back(CI);
> +            }
> +          }
> +        }
> +
> +        // Find and remove the unregister calls.
> +        for (SmallVectorImpl<BasicBlock*>::iterator I = ReturnList.begin(),
> +               E = ReturnList.end(); I != E; ++I) {
> +          BasicBlock *BB = *I;
> +          typedef BasicBlock::InstListType::reverse_iterator reverse_iterator;
> +
> +          for (reverse_iterator II = BB->getInstList().rbegin(),
> +                 IE = BB->getInstList().rend(); II != IE; ++II) {
> +            if (CallInst *CI = dyn_cast<CallInst>(&*II)) {
> +              Value *Callee = CI->getCalledValue();
> +
> +              if (Callee == UnregisterFn) {
> +                DeadInsts.push_back(CI);
> +                break;
> +              }
> +            }
> +          }
> +        }
> +
> +        // Kill the dead instructions.
> +        for (SmallVectorImpl<Instruction*>::iterator I = DeadInsts.begin(),
> +               E = DeadInsts.end(); I != E; ++I)
> +          (*I)->eraseFromParent();
> +      }
> +    }
> +
>       // Merge pairs of basic blocks with unconditional branches, connected by
>       // a single edge.
>       if (EverMadeChange || MadeChange)
>
> Modified: llvm/trunk/test/CodeGen/ARM/crash.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/crash.ll?rev=168930&r1=168929&r2=168930&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/crash.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/crash.ll Thu Nov 29 13:38:06 2012
> @@ -69,3 +69,26 @@
>     store <4 x float> %tmp154, <4 x float>* undef, align 16
>     ret void
>   }
> +
> +; <rdar://problem/12721258>
> +%A = type { %B }
> +%B = type { i32 }
> +
> +define void @_Z3Foov() ssp {
> +entry:
> +  br i1 true, label %exit, label %false
> +
> +false:
> +  invoke void undef(%A* undef)
> +          to label %exit unwind label %lpad
> +
> +lpad:
> +  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*)
> +          catch i8* null
> +  unreachable
> +
> +exit:
> +  ret void
> +}
> +
> +declare i32 @__gxx_personality_sj0(...)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list