[llvm-commits] CVS: llvm/lib/VMCore/AutoUpgrade.cpp

Reid Spencer reid at x10sys.com
Fri Jan 27 03:49:41 PST 2006



Changes in directory llvm/lib/VMCore:

AutoUpgrade.cpp updated: 1.7 -> 1.8
---
Log message:

Fix auto-upgrade of intrinsics to work properly with both assembly and
bytecode reading. This code is crufty, the result of much hacking to get things
working correctly. Cleanup patches will follow.


---
Diffs of the changes:  (+98 -28)

 AutoUpgrade.cpp |  126 +++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 98 insertions(+), 28 deletions(-)


Index: llvm/lib/VMCore/AutoUpgrade.cpp
diff -u llvm/lib/VMCore/AutoUpgrade.cpp:1.7 llvm/lib/VMCore/AutoUpgrade.cpp:1.8
--- llvm/lib/VMCore/AutoUpgrade.cpp:1.7	Mon Jan 23 01:42:30 2006
+++ llvm/lib/VMCore/AutoUpgrade.cpp	Fri Jan 27 05:49:27 2006
@@ -75,9 +75,26 @@
   return 0;
 }
 
+// This assumes the Function is one of the intrinsics we upgraded.
+static inline const Type* getTypeFromFunction(Function *F) {
+  const Type* Ty = F->getReturnType();
+  if (Ty->isFloatingPoint())
+    return Ty;
+  if (Ty->isSigned())
+    return Ty->getUnsignedVersion();
+  if (Ty->isInteger())
+    return Ty;
+  if (Ty == Type::BoolTy) {
+    Function::const_arg_iterator ArgIt = F->arg_begin();
+    if (ArgIt != F->arg_end()) 
+      return ArgIt->getType();
+  }
+  return 0;
+}
+
 bool llvm::IsUpgradeableIntrinsicName(const std::string& Name) {
   // Quickly eliminate it, if it's not a candidate.
-  if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || Name[2] !=
+  if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || Name[2] !=
     'v' || Name[3] != 'm' || Name[4] != '.')
     return false;
 
@@ -140,23 +157,68 @@
   return 0;
 }
 
-Instruction* llvm::UpgradeIntrinsicCall(CallInst *CI) {
+
+Instruction* llvm::MakeUpgradedCall(
+    Function* F, const std::vector<Value*>& Params, BasicBlock* BB,
+    bool isTailCall, unsigned CallingConv) {
+  assert(F && "Need a Function to make a CallInst");
+  assert(BB && "Need a BasicBlock to make a CallInst");
+
+  // Convert the params
+  bool signedArg = false;
+  std::vector<Value*> Oprnds;
+  for (std::vector<Value*>::const_iterator PI = Params.begin(), 
+       PE = Params.end(); PI != PE; ++PI) {
+    const Type* opTy = (*PI)->getType();
+    if (opTy->isSigned()) {
+      signedArg = true;
+      CastInst* cast = 
+        new CastInst(*PI,opTy->getUnsignedVersion(), "autoupgrade_cast");
+      BB->getInstList().push_back(cast);
+      Oprnds.push_back(cast);
+    }
+    else
+      Oprnds.push_back(*PI);
+  }
+
+  Instruction* result = new CallInst(F,Oprnds,"autoupgrade_call");
+  if (isTailCall) cast<CallInst>(result)->setTailCall();
+  if (CallingConv) cast<CallInst>(result)->setCallingConv(CallingConv);
+  if (signedArg) {
+    const Type* newTy = F->getReturnType()->getUnsignedVersion();
+    CastInst* final = new CastInst(result, newTy, "autoupgrade_uncast");
+    BB->getInstList().push_back(result);
+    result = final;
+  }
+  return result;
+}
+
+Instruction* llvm::UpgradeIntrinsicCall(CallInst *CI, Function* newF) {
   Function *F = CI->getCalledFunction();
-  if (const Type* Ty = getTypeFromFunctionName(F)) {
-    Function* newF = UpgradeIntrinsicFunction(F);
+  if (const Type* Ty = 
+      (newF ? getTypeFromFunction(newF) : getTypeFromFunctionName(F))) {
     std::vector<Value*> Oprnds;
-    for (User::op_iterator OI = CI->op_begin(), OE = CI->op_end(); 
-         OI != OE; ++OI)
-      Oprnds.push_back(CI);
-    CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI);
-    if (Ty->isSigned()) {
-      const Type* newTy = Ty->getUnsignedVersion();
-      newCI->setOperand(1,new CastInst(newCI->getOperand(1), newTy, 
-                     "autoupgrade_cast", newCI));
-      CastInst* final = new CastInst(newCI, Ty, "autoupgrade_uncast",newCI);
-      newCI->moveBefore(final);
-      return final;
+    User::op_iterator OI = CI->op_begin(); 
+    ++OI;
+    for (User::op_iterator OE = CI->op_end() ; OI != OE; ++OI) {
+      const Type* opTy = OI->get()->getType();
+      if (opTy->isSigned())
+        Oprnds.push_back(
+          new CastInst(OI->get(),opTy->getUnsignedVersion(), 
+            "autoupgrade_cast",CI));
+      else
+        Oprnds.push_back(*OI);
     }
+    CallInst* newCI = new CallInst((newF?newF:F),Oprnds,"autoupgrade_call",CI);
+    newCI->setTailCall(CI->isTailCall());
+    newCI->setCallingConv(CI->getCallingConv());
+    if (const Type* oldType = CI->getCalledFunction()->getReturnType())
+      if (oldType->isSigned()) {
+        CastInst* final = 
+          new CastInst(newCI, oldType, "autoupgrade_uncast",newCI);
+        newCI->moveBefore(final);
+        return final;
+      }
     return newCI;
   }
   return 0;
@@ -170,20 +232,28 @@
         std::vector<Value*> Oprnds;
         User::op_iterator OI = CI->op_begin();
         ++OI;
-        for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI)
-          Oprnds.push_back(*OI);
-        CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI);
-        const Type* Ty = Oprnds[0]->getType();
-        if (Ty->isSigned()) {
-          const Type* newTy = Ty->getUnsignedVersion();
-          newCI->setOperand(1,new CastInst(newCI->getOperand(1), newTy, 
-                         "autoupgrade_cast", newCI));
-          CastInst* final = new CastInst(newCI, Ty, "autoupgrade_uncast",newCI);
-          newCI->moveBefore(final);
-          CI->replaceAllUsesWith(final);
-        } else {
-          CI->replaceAllUsesWith(newCI);
+        for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI) {
+          const Type* opTy = OI->get()->getType();
+          if (opTy->isSigned()) {
+            Oprnds.push_back(
+              new CastInst(OI->get(),opTy->getUnsignedVersion(), 
+                  "autoupgrade_cast",CI));
+          }
+          else
+            Oprnds.push_back(*OI);
         }
+        CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI);
+        newCI->setTailCall(CI->isTailCall());
+        newCI->setCallingConv(CI->getCallingConv());
+        if (const Type* Ty = CI->getCalledFunction()->getReturnType())
+          if (Ty->isSigned()) {
+            CastInst* final = 
+              new CastInst(newCI, Ty, "autoupgrade_uncast",newCI);
+            newCI->moveBefore(final);
+            CI->replaceAllUsesWith(final);
+          } else {
+            CI->replaceAllUsesWith(newCI);
+          }
         CI->eraseFromParent();
       }
     }






More information about the llvm-commits mailing list