[llvm-commits] [llvm] r42021 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Duncan Sands baldrick at free.fr
Mon Sep 17 03:26:40 PDT 2007


Author: baldrick
Date: Mon Sep 17 05:26:40 2007
New Revision: 42021

URL: http://llvm.org/viewvc/llvm-project?rev=42021&view=rev
Log:
Factor the trampoline transformation into a subroutine.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42021&r1=42020&r2=42021&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 17 05:26:40 2007
@@ -235,6 +235,7 @@
   private:
     Instruction *visitCallSite(CallSite CS);
     bool transformConstExprCastCall(CallSite CS);
+    Instruction *transformCallThroughTrampoline(CallSite CS);
 
   public:
     // InsertNewInstBefore - insert an instruction New before instruction Old
@@ -7834,6 +7835,11 @@
     return EraseInstFromFunction(*CS.getInstruction());
   }
 
+  if (BitCastInst *BC = dyn_cast<BitCastInst>(Callee))
+    if (IntrinsicInst *In = dyn_cast<IntrinsicInst>(BC->getOperand(0)))
+      if (In->getIntrinsicID() == Intrinsic::init_trampoline)
+        return transformCallThroughTrampoline(CS);
+
   const PointerType *PTy = cast<PointerType>(Callee->getType());
   const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
   if (FTy->isVarArg()) {
@@ -7852,143 +7858,6 @@
       }
   }
 
-  if (BitCastInst *BC = dyn_cast<BitCastInst>(Callee)) {
-    IntrinsicInst *In = dyn_cast<IntrinsicInst>(BC->getOperand(0));
-    if (In && In->getIntrinsicID() == Intrinsic::init_trampoline) {
-      Function *NestF =
-        cast<Function>(IntrinsicInst::StripPointerCasts(In->getOperand(2)));
-      const PointerType *NestFPTy = cast<PointerType>(NestF->getType());
-      const FunctionType *NestFTy =
-        cast<FunctionType>(NestFPTy->getElementType());
-
-      if (const ParamAttrsList *NestAttrs = NestFTy->getParamAttrs()) {
-        unsigned NestIdx = 1;
-        const Type *NestTy = 0;
-        uint16_t NestAttr = 0;
-
-        Instruction *Caller = CS.getInstruction();
-
-        // Look for a parameter marked with the 'nest' attribute.
-        for (FunctionType::param_iterator I = NestFTy->param_begin(),
-             E = NestFTy->param_end(); I != E; ++NestIdx, ++I)
-          if (NestAttrs->paramHasAttr(NestIdx, ParamAttr::Nest)) {
-            // Record the parameter type and any other attributes.
-            NestTy = *I;
-            NestAttr = NestAttrs->getParamAttrs(NestIdx);
-            break;
-          }
-
-        if (NestTy) {
-          std::vector<Value*> NewArgs;
-          NewArgs.reserve(unsigned(CS.arg_end()-CS.arg_begin())+1);
-
-          // Insert the nest argument into the call argument list, which may
-          // mean appending it.
-          {
-            unsigned Idx = 1;
-            CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
-            do {
-              if (Idx == NestIdx) {
-                // Add the chain argument.
-                Value *NestVal = In->getOperand(3);
-                if (NestVal->getType() != NestTy)
-                  NestVal = new BitCastInst(NestVal, NestTy, "nest", Caller);
-                NewArgs.push_back(NestVal);
-              }
-
-              if (I == E)
-                break;
-
-              // Add the original argument.
-              NewArgs.push_back(*I);
-
-              ++Idx, ++I;
-            } while (1);
-          }
-
-          // The trampoline may have been bitcast to a bogus type (FTy).
-          // Handle this by synthesizing a new function type, equal to FTy
-          // with the chain parameter inserted.  Likewise for attributes.
-
-          const ParamAttrsList *Attrs = FTy->getParamAttrs();
-          std::vector<const Type*> NewTypes;
-          ParamAttrsVector NewAttrs;
-          NewTypes.reserve(FTy->getNumParams()+1);
-
-          // Add any function result attributes.
-          uint16_t Attr = Attrs ? Attrs->getParamAttrs(0) : 0;
-          if (Attr)
-            NewAttrs.push_back (ParamAttrsWithIndex::get(0, Attr));
-
-          // Insert the chain's type into the list of parameter types, which may
-          // mean appending it.  Likewise for the chain's attributes.
-          {
-            unsigned Idx = 1;
-            FunctionType::param_iterator I = FTy->param_begin(),
-              E = FTy->param_end();
-
-            do {
-              if (Idx == NestIdx) {
-                // Add the chain's type and attributes.
-                NewTypes.push_back(NestTy);
-                NewAttrs.push_back(ParamAttrsWithIndex::get(NestIdx, NestAttr));
-              }
-
-              if (I == E)
-                break;
-
-              // Add the original type and attributes.
-              NewTypes.push_back(*I);
-              Attr = Attrs ? Attrs->getParamAttrs(Idx) : 0;
-              if (Attr)
-                NewAttrs.push_back
-                  (ParamAttrsWithIndex::get(Idx + (Idx >= NestIdx), Attr));
-
-              ++Idx, ++I;
-            } while (1);
-          }
-
-          // Replace the trampoline call with a direct call.  Let the generic
-          // code sort out any function type mismatches.
-          FunctionType *NewFTy =
-            FunctionType::get(FTy->getReturnType(), NewTypes, FTy->isVarArg(),
-                              ParamAttrsList::get(NewAttrs));
-          Constant *NewCallee = NestF->getType() == PointerType::get(NewFTy) ?
-            NestF : ConstantExpr::getBitCast(NestF, PointerType::get(NewFTy));
-
-          Instruction *NewCaller;
-          if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
-            NewCaller = new InvokeInst(NewCallee, II->getNormalDest(),
-                                       II->getUnwindDest(), NewArgs.begin(),
-                                       NewArgs.end(), Caller->getName(),
-                                       Caller);
-            cast<InvokeInst>(NewCaller)->setCallingConv(II->getCallingConv());
-          } else {
-            NewCaller = new CallInst(NewCallee, NewArgs.begin(), NewArgs.end(),
-                                     Caller->getName(), Caller);
-            if (cast<CallInst>(Caller)->isTailCall())
-              cast<CallInst>(NewCaller)->setTailCall();
-            cast<CallInst>(NewCaller)->
-              setCallingConv(cast<CallInst>(Caller)->getCallingConv());
-          }
-          if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
-            Caller->replaceAllUsesWith(NewCaller);
-          Caller->eraseFromParent();
-          RemoveFromWorkList(Caller);
-          return 0;
-        }
-      }
-
-      // Replace the trampoline call with a direct call.  Since there is no
-      // 'nest' parameter, there is no need to adjust the argument list.  Let
-      // the generic code sort out any function type mismatches.
-      Constant *NewCallee = NestF->getType() == PTy ?
-        NestF : ConstantExpr::getBitCast(NestF, PTy);
-      CS.setCalledFunction(NewCallee);
-      Changed = true;
-    }
-  }
-
   return Changed ? CS.getInstruction() : 0;
 }
 
@@ -8191,6 +8060,148 @@
   return true;
 }
 
+// transformCallThroughTrampoline - Turn a call to a function created by the
+// init_trampoline intrinsic into a direct call to the underlying function.
+//
+Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
+  Value *Callee = CS.getCalledValue();
+  const PointerType *PTy = cast<PointerType>(Callee->getType());
+  const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+
+  IntrinsicInst *Tramp =
+    cast<IntrinsicInst>(cast<BitCastInst>(Callee)->getOperand(0));
+
+  Function *NestF =
+    cast<Function>(IntrinsicInst::StripPointerCasts(Tramp->getOperand(2)));
+  const PointerType *NestFPTy = cast<PointerType>(NestF->getType());
+  const FunctionType *NestFTy = cast<FunctionType>(NestFPTy->getElementType());
+
+  if (const ParamAttrsList *NestAttrs = NestFTy->getParamAttrs()) {
+    unsigned NestIdx = 1;
+    const Type *NestTy = 0;
+    uint16_t NestAttr = 0;
+
+    // Look for a parameter marked with the 'nest' attribute.
+    for (FunctionType::param_iterator I = NestFTy->param_begin(),
+         E = NestFTy->param_end(); I != E; ++NestIdx, ++I)
+      if (NestAttrs->paramHasAttr(NestIdx, ParamAttr::Nest)) {
+        // Record the parameter type and any other attributes.
+        NestTy = *I;
+        NestAttr = NestAttrs->getParamAttrs(NestIdx);
+        break;
+      }
+
+    if (NestTy) {
+      Instruction *Caller = CS.getInstruction();
+      std::vector<Value*> NewArgs;
+      NewArgs.reserve(unsigned(CS.arg_end()-CS.arg_begin())+1);
+
+      // Insert the nest argument into the call argument list, which may
+      // mean appending it.
+      {
+        unsigned Idx = 1;
+        CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
+        do {
+          if (Idx == NestIdx) {
+            // Add the chain argument.
+            Value *NestVal = Tramp->getOperand(3);
+            if (NestVal->getType() != NestTy)
+              NestVal = new BitCastInst(NestVal, NestTy, "nest", Caller);
+            NewArgs.push_back(NestVal);
+          }
+
+          if (I == E)
+            break;
+
+          // Add the original argument.
+          NewArgs.push_back(*I);
+
+          ++Idx, ++I;
+        } while (1);
+      }
+
+      // The trampoline may have been bitcast to a bogus type (FTy).
+      // Handle this by synthesizing a new function type, equal to FTy
+      // with the chain parameter inserted.  Likewise for attributes.
+
+      const ParamAttrsList *Attrs = FTy->getParamAttrs();
+      std::vector<const Type*> NewTypes;
+      ParamAttrsVector NewAttrs;
+      NewTypes.reserve(FTy->getNumParams()+1);
+
+      // Add any function result attributes.
+      uint16_t Attr = Attrs ? Attrs->getParamAttrs(0) : 0;
+      if (Attr)
+        NewAttrs.push_back (ParamAttrsWithIndex::get(0, Attr));
+
+      // Insert the chain's type into the list of parameter types, which may
+      // mean appending it.  Likewise for the chain's attributes.
+      {
+        unsigned Idx = 1;
+        FunctionType::param_iterator I = FTy->param_begin(),
+          E = FTy->param_end();
+
+        do {
+          if (Idx == NestIdx) {
+            // Add the chain's type and attributes.
+            NewTypes.push_back(NestTy);
+            NewAttrs.push_back(ParamAttrsWithIndex::get(NestIdx, NestAttr));
+          }
+
+          if (I == E)
+            break;
+
+          // Add the original type and attributes.
+          NewTypes.push_back(*I);
+          Attr = Attrs ? Attrs->getParamAttrs(Idx) : 0;
+          if (Attr)
+            NewAttrs.push_back
+              (ParamAttrsWithIndex::get(Idx + (Idx >= NestIdx), Attr));
+
+          ++Idx, ++I;
+        } while (1);
+      }
+
+      // Replace the trampoline call with a direct call.  Let the generic
+      // code sort out any function type mismatches.
+      FunctionType *NewFTy =
+        FunctionType::get(FTy->getReturnType(), NewTypes, FTy->isVarArg(),
+                          ParamAttrsList::get(NewAttrs));
+      Constant *NewCallee = NestF->getType() == PointerType::get(NewFTy) ?
+        NestF : ConstantExpr::getBitCast(NestF, PointerType::get(NewFTy));
+
+      Instruction *NewCaller;
+      if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
+        NewCaller = new InvokeInst(NewCallee,
+                                   II->getNormalDest(), II->getUnwindDest(),
+                                   NewArgs.begin(), NewArgs.end(),
+                                   Caller->getName(), Caller);
+        cast<InvokeInst>(NewCaller)->setCallingConv(II->getCallingConv());
+      } else {
+        NewCaller = new CallInst(NewCallee, NewArgs.begin(), NewArgs.end(),
+                                 Caller->getName(), Caller);
+        if (cast<CallInst>(Caller)->isTailCall())
+          cast<CallInst>(NewCaller)->setTailCall();
+        cast<CallInst>(NewCaller)->
+          setCallingConv(cast<CallInst>(Caller)->getCallingConv());
+      }
+      if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
+        Caller->replaceAllUsesWith(NewCaller);
+      Caller->eraseFromParent();
+      RemoveFromWorkList(Caller);
+      return 0;
+    }
+  }
+
+  // Replace the trampoline call with a direct call.  Since there is no 'nest'
+  // parameter, there is no need to adjust the argument list.  Let the generic
+  // code sort out any function type mismatches.
+  Constant *NewCallee =
+    NestF->getType() == PTy ? NestF : ConstantExpr::getBitCast(NestF, PTy);
+  CS.setCalledFunction(NewCallee);
+  return CS.getInstruction();
+}
+
 /// FoldPHIArgBinOpIntoPHI - If we have something like phi [add (a,b), add(c,d)]
 /// and if a/b/c/d and the add's all have a single use, turn this into two phi's
 /// and a single binop.





More information about the llvm-commits mailing list