If we support structs as va_list, we must pass pointers to them to va_copy
authorAndrew Lenharth <andrewl@lenharth.org>
Wed, 22 Jun 2005 21:04:42 +0000 (21:04 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Wed, 22 Jun 2005 21:04:42 +0000 (21:04 +0000)
See last commit for LangRef, this implements it on all targets.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22273 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/llvmAsmParser.y
lib/Bytecode/Reader/ReaderWrappers.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/CBackend/Writer.cpp
lib/Target/IA64/IA64ISelPattern.cpp
lib/Target/PowerPC/PPC64ISelPattern.cpp
lib/Target/SparcV9/SparcV9BurgISel.cpp
lib/Target/X86/X86ISelPattern.cpp

index b71f618779be2d33c00751c437d9123fb369d038..178c533093464305cff884519767785e66d9a749 100644 (file)
@@ -749,14 +749,12 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
   }
 
   if (ObsoleteVarArgs && NewVarArgs)
-  {
-    std::cerr << "This file is corrupt in that it uses both new and old style varargs\n";
-    abort();
-  }
+    ThrowException("This file is corrupt in that it uses both new and old style varargs");
 
   if(ObsoleteVarArgs) {
     if(Function* F = Result->getNamedFunction("llvm.va_start")) {
-      assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
+      if (F->arg_size() != 0)
+        ThrowException("Obsolete va_start takes 0 argument!");
       
       //foo = va_start()
       // ->
@@ -782,7 +780,9 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
     }
     
     if(Function* F = Result->getNamedFunction("llvm.va_end")) {
-      assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!");
+      if(F->arg_size() != 1)
+        ThrowException("Obsolete va_end takes 1 argument!");
+
       //vaend foo
       // ->
       //bar = alloca 1 of typeof(foo)
@@ -804,24 +804,29 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
     }
 
     if(Function* F = Result->getNamedFunction("llvm.va_copy")) {
-      assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!");
+      if(F->arg_size() != 1)
+        ThrowException("Obsolete va_copy takes 1 argument!");
       //foo = vacopy(bar)
       // ->
       //a = alloca 1 of typeof(foo)
-      //vacopy(a, bar)
+      //b = alloca 1 of typeof(foo)
+      //store bar -> b
+      //vacopy(a, b)
       //foo = load a
       
       const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
       const Type* ArgTy = F->getFunctionType()->getReturnType();
       const Type* ArgTyPtr = PointerType::get(ArgTy);
       Function* NF = Result->getOrInsertFunction("llvm.va_copy", 
-                                                 RetTy, ArgTyPtr, ArgTy, 0);
+                                                 RetTy, ArgTyPtr, ArgTyPtr, 0);
 
       while (!F->use_empty()) {
         CallInst* CI = cast<CallInst>(F->use_back());
         AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
-        new CallInst(NF, a, CI->getOperand(1), "", CI);
-        Value* foo = new LoadInst(a, "vacopy.fix.2", CI);
+        AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
+        new StoreInst(CI->getOperand(1), b, CI);
+        new CallInst(NF, a, b, "", CI);
+        Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
         CI->replaceAllUsesWith(foo);
         CI->getParent()->getInstList().erase(CI);
       }
index c000c9a3f59291e907b28e556cd794af2e2b1957..a198447d72c11d898214ae4e7ea8b2f0041dfe44 100644 (file)
@@ -221,20 +221,24 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
     //foo = vacopy(bar)
     // ->
     //a = alloca 1 of typeof(foo)
-    //vacopy(a, bar)
+    //b = alloca 1 of typeof(foo)
+    //store bar -> b
+    //vacopy(a, b)
     //foo = load a
     
     const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
     const Type* ArgTy = F->getFunctionType()->getReturnType();
     const Type* ArgTyPtr = PointerType::get(ArgTy);
     Function* NF = M->getOrInsertFunction("llvm.va_copy", 
-                                          RetTy, ArgTyPtr, ArgTy, 0);
+                                          RetTy, ArgTyPtr, ArgTyPtr, 0);
     
     for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
       if (CallInst* CI = dyn_cast<CallInst>(*I++)) {
         AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
-        new CallInst(NF, a, CI->getOperand(1), "", CI);
-        Value* foo = new LoadInst(a, "vacopy.fix.2", CI);
+        AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
+        new StoreInst(CI->getOperand(1), b, CI);
+        new CallInst(NF, a, b, "", CI);
+        Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
         CI->replaceAllUsesWith(foo);
         CI->getParent()->getInstList().erase(CI);
       }
index 0c94ea74cd9d2013323dca5c9d8dda3503edcbd1..fa6d6d4d14cdc668fd551abe56a98f14ddb83017 100644 (file)
@@ -855,10 +855,11 @@ SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand L,
 std::pair<SDOperand,SDOperand>
 TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, 
                             SelectionDAG &DAG) {
-  // We have no sane default behavior, just emit a useful error message and bail
-  // out.
-  std::cerr << "Variable arguments handling not implemented on this target!\n";
-  abort();
+  //Default to returning the input list
+  SDOperand Val = DAG.getLoad(getPointerTy(), Chain, Src, DAG.getSrcValue(NULL));
+  SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
+                                 Val, Dest, DAG.getSrcValue(NULL));
+  return std::make_pair(Result, Result);
 }
 
 std::pair<SDOperand,SDOperand>
index 65979933dbb585387331396d9be61b4b9a6b21b5..c30b306483e4b2a9bbf8dbb3b4d8cabca2283c1f 100644 (file)
@@ -1495,7 +1495,7 @@ void CWriter::visitCallInst(CallInst &I) {
         Out << "0; ";
         Out << "va_copy(*(va_list*)";
         writeOperand(I.getOperand(1));
-        Out << ", *(va_list*)&";
+        Out << ", *(va_list*)";
         writeOperand(I.getOperand(2));
         Out << ')';
         return;
index 65979933dbb585387331396d9be61b4b9a6b21b5..c30b306483e4b2a9bbf8dbb3b4d8cabca2283c1f 100644 (file)
@@ -1495,7 +1495,7 @@ void CWriter::visitCallInst(CallInst &I) {
         Out << "0; ";
         Out << "va_copy(*(va_list*)";
         writeOperand(I.getOperand(1));
-        Out << ", *(va_list*)&";
+        Out << ", *(va_list*)";
         writeOperand(I.getOperand(2));
         Out << ')';
         return;
index 0830468a959baeb322f5daea4c640d26d4a0c376..804ad9937ef6fa2321dd3a266a08028e471e673c 100644 (file)
@@ -120,10 +120,6 @@ namespace {
     LowerVAArgNext(SDOperand Chain, SDOperand VAList,
                    const Type *ArgTy, SelectionDAG &DAG);
 
-    virtual std::pair<SDOperand,SDOperand>
-    LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, 
-                SelectionDAG &DAG);
-
     virtual std::pair<SDOperand, SDOperand>
     LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                             SelectionDAG &DAG);
@@ -413,15 +409,6 @@ LowerVAArgNext(SDOperand Chain, SDOperand VAList,
   return std::make_pair(Result, Chain);
 }
 
-std::pair<SDOperand,SDOperand>
-IA64TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, 
-                                SDOperand Dest, SelectionDAG &DAG)
-{
-  SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                 Src, Dest, DAG.getSrcValue(NULL));
-  return std::make_pair(Result, Result);
-}
-
 std::pair<SDOperand, SDOperand> IA64TargetLowering::
 LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
                         SelectionDAG &DAG) {
index 20fd7244447b037df5099629bcaccdcba0622cb1..6761ab1115cba9593eb0d52e582502a80af561f7 100644 (file)
@@ -104,10 +104,6 @@ namespace {
     LowerVAArgNext(SDOperand Chain, SDOperand VAList,
                    const Type *ArgTy, SelectionDAG &DAG);
 
-    virtual std::pair<SDOperand,SDOperand>
-    LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest,
-                SelectionDAG &DAG);
-
     virtual std::pair<SDOperand, SDOperand>
     LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                             SelectionDAG &DAG);
@@ -390,16 +386,6 @@ LowerVAArgNext(SDOperand Chain, SDOperand VAList,
   return std::make_pair(Result, Chain);
 }
 
-std::pair<SDOperand,SDOperand>
-PPC64TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, 
-                                 SDOperand Dest, SelectionDAG &DAG)
-{
-  SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                 Src, Dest, DAG.getSrcValue(NULL));
-  return std::make_pair(Result, Result);
-}
-
-
 std::pair<SDOperand, SDOperand> PPC64TargetLowering::
 LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
                         SelectionDAG &DAG) {
index cc2c81f3bb77aa81189c5fb5289460b4911a7794..a6722b1862f476c46c0d676d7ab5ea8e487dfab3 100644 (file)
@@ -2881,11 +2881,18 @@ static bool CodeGenIntrinsic(Intrinsic::ID iid, CallInst &callInstr,
     return true;                        // no-op on SparcV9
 
   case Intrinsic::vacopy:
-    // Simple store of current va_list (arg2) to new va_list (arg1)
-    mvec.push_back(BuildMI(V9::STXi, 3).
-                   addReg(callInstr.getOperand(2)).
-                   addReg(callInstr.getOperand(1)).addSImm(0));
-    return true;
+    {
+      MachineCodeForInstruction& m1 = MachineCodeForInstruction::get(&callInstr);
+      TmpInstruction* VReg = 
+        new TmpInstruction(m1, callInstr.getOperand(1)->getType());
+      
+      // Simple store of current va_list (arg2) to new va_list (arg1)
+      mvec.push_back(BuildMI(V9::LDXi, 3).
+                     addReg(callInstr.getOperand(2)).addSImm(0).addRegDef(VReg));
+      mvec.push_back(BuildMI(V9::STXi, 3).
+                     addReg(VReg).addReg(callInstr.getOperand(1)).addSImm(0));
+      return true;
+    }
   }
 }
 
index d28de2828d65f53beccc7e19c24be4ed97905c4d..e858c4c821250a138a953245dd93d977006853bf 100644 (file)
@@ -182,10 +182,6 @@ namespace {
     LowerVAArgNext(SDOperand Chain, SDOperand VAList,
                    const Type *ArgTy, SelectionDAG &DAG);
 
-    virtual std::pair<SDOperand,SDOperand>
-    LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, 
-                SelectionDAG &DAG);
-
     virtual std::pair<SDOperand, SDOperand>
     LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                             SelectionDAG &DAG);
@@ -475,15 +471,6 @@ X86TargetLowering::LowerVAArgNext(SDOperand Chain, SDOperand VAList,
   return std::make_pair(Result, Chain);
 }
 
-std::pair<SDOperand,SDOperand>
-X86TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, 
-                               SDOperand Dest, SelectionDAG &DAG)
-{
-  SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                 Src, Dest, DAG.getSrcValue(NULL));
-  return std::make_pair(Result, Result);
-}
-
 //===----------------------------------------------------------------------===//
 //                    Fast Calling Convention implementation
 //===----------------------------------------------------------------------===//