encode calling conventions for call/invoke instructions.
authorChris Lattner <sabre@nondot.org>
Fri, 6 May 2005 22:34:01 +0000 (22:34 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 6 May 2005 22:34:01 +0000 (22:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21751 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Writer/Writer.cpp

index 8e46083082f9a6632f75066406ce4db96cc12116..e48f64178c17cf76f6761ad9d1126796199d2d06 100644 (file)
 #include "Reader.h"
 #include "llvm/Bytecode/BytecodeHandler.h"
 #include "llvm/BasicBlock.h"
-#include "llvm/Config/alloca.h"
+#include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/Instructions.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/Bytecode/Format.h"
+#include "llvm/Config/alloca.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/Compressor.h"
 #include "llvm/ADT/StringExtras.h"
@@ -720,13 +721,22 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
     break;
   }
 
-  case 61:  // tail call
-  case Instruction::Call: {
+  case 58:                   // Call with extra operand for calling conv
+  case 59:                   // tail call, Fast CC
+  case 60:                   // normal call, Fast CC
+  case 61:                   // tail call, C Calling Conv
+  case Instruction::Call: {  // Normal Call, C Calling Convention
     if (Oprnds.size() == 0)
       error("Invalid call instruction encountered!");
 
     Value *F = getValue(iType, Oprnds[0]);
 
+    unsigned CallingConv = CallingConv::C;
+    bool isTailCall = false;
+
+    if (Opcode == 61 || Opcode == 59)
+      isTailCall = true;
+
     // Check to make sure we have a pointer to function type
     const PointerType *PTy = dyn_cast<PointerType>(F->getType());
     if (PTy == 0) error("Call to non function pointer value!");
@@ -737,6 +747,13 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
     if (!FTy->isVarArg()) {
       FunctionType::param_iterator It = FTy->param_begin();
 
+      if (Opcode == 58) {
+        isTailCall = Oprnds.back() & 1;
+        CallingConv = Oprnds.back() >> 1;
+        Oprnds.pop_back();
+      } else if (Opcode == 59 || Opcode == 60)
+        CallingConv = CallingConv::Fast;
+
       for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
         if (It == FTy->param_end())
           error("Invalid call instruction!");
@@ -766,10 +783,13 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
     }
 
     Result = new CallInst(F, Params);
-    if (Opcode == 61) cast<CallInst>(Result)->setTailCall(true);
+    if (isTailCall) cast<CallInst>(Result)->setTailCall();
+    if (CallingConv) cast<CallInst>(Result)->setCallingConv(CallingConv);
     break;
   }
-  case Instruction::Invoke: {
+  case 56:                     // Invoke with encoded CC
+  case 57:                     // Invoke Fast CC
+  case Instruction::Invoke: {  // Invoke C CC
     if (Oprnds.size() < 3)
       error("Invalid invoke instruction!");
     Value *F = getValue(iType, Oprnds[0]);
@@ -784,6 +804,14 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
 
     std::vector<Value *> Params;
     BasicBlock *Normal, *Except;
+    unsigned CallingConv = CallingConv::C;
+
+    if (Opcode == 57)
+      CallingConv = CallingConv::Fast;
+    else if (Opcode == 56) {
+      CallingConv = Oprnds.back();
+      Oprnds.pop_back();
+    }
 
     if (!FTy->isVarArg()) {
       Normal = getBasicBlock(Oprnds[1]);
@@ -816,6 +844,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
     }
 
     Result = new InvokeInst(F, Normal, Except, Params);
+    if (CallingConv) cast<InvokeInst>(Result)->setCallingConv(CallingConv);
     break;
   }
   case Instruction::Malloc:
@@ -2043,8 +2072,9 @@ void BytecodeReader::ParseVersionInfo() {
 
     // FALL THROUGH
 
-  case 5:               // 1.x.x (Not Released)
+  case 5:               // 1.4 (Released)
     break;
+#if 0
     // FIXME: NONE of this is implemented yet!
 
     // In version 5, basic blocks have a minimum index of 0 whereas all the
@@ -2061,7 +2091,7 @@ void BytecodeReader::ParseVersionInfo() {
     // integer value 0x01 to identify the module block. This is unnecessary and
     // removed in version 5.
     hasUnnecessaryModuleBlockId = true;
-
+#endif
   default:
     error("Unknown bytecode version number: " + itostr(RevisionNum));
   }
index 4cf4cf5a97d0e21ed5e3d21715fb35b5db7616c2..81c86d6ffabcbcb3b8141db226a4c4ad61b81cb5 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "WriterInternals.h"
 #include "llvm/Bytecode/WriteBytecodePass.h"
+#include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
@@ -425,7 +426,7 @@ void BytecodeWriter::outputConstantStrings() {
 typedef unsigned char uchar;
 
 // outputInstructionFormat0 - Output those weird instructions that have a large
-// number of operands or have large operands themselves...
+// number of operands or have large operands themselves.
 //
 // Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
 //
@@ -439,7 +440,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
 
   unsigned NumArgs = I->getNumOperands();
   output_vbr(NumArgs + (isa<CastInst>(I) || isa<VANextInst>(I) ||
-                        isa<VAArgInst>(I)));
+                        isa<VAArgInst>(I) || Opcode == 56 || Opcode == 58));
 
   if (!isa<GetElementPtrInst>(&I)) {
     for (unsigned i = 0; i < NumArgs; ++i) {
@@ -456,8 +457,12 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
       int Slot = Table.getSlot(VAI->getArgType());
       assert(Slot != -1 && "VarArg argument type unknown?");
       output_typeid((unsigned)Slot);
+    } else if (Opcode == 56) {  // Invoke escape sequence
+      output_vbr(cast<InvokeInst>(I)->getCallingConv());
+    } else if (Opcode == 58) {  // Call escape sequence
+      output_vbr((cast<CallInst>(I)->getCallingConv() << 1) |
+                 cast<CallInst>(I)->isTailCall());
     }
-
   } else {
     int Slot = Table.getSlot(I->getOperand(0));
     assert(Slot >= 0 && "No slot number for value!?!?");
@@ -608,12 +613,31 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
 
   // Encode 'tail call' as 61, 'volatile load' as 62, and 'volatile store' as
   // 63.
-  if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall())
-    Opcode = 61;
-  if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile())
+  if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
+    if (CI->getCallingConv() == CallingConv::C) {
+      if (CI->isTailCall())
+        Opcode = 61;   // CCC + Tail Call
+      else
+        ;     // Opcode = Instruction::Call
+    } else if (CI->getCallingConv() == CallingConv::Fast) {
+      if (CI->isTailCall())
+        Opcode = 59;    // FastCC + TailCall
+      else
+        Opcode = 60;    // FastCC + Not Tail Call
+    } else {
+      Opcode = 58;      // Call escape sequence.
+    }
+  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
+    if (II->getCallingConv() == CallingConv::Fast)
+      Opcode = 57;      // FastCC invoke.
+    else if (II->getCallingConv() != CallingConv::C)
+      Opcode = 56;      // Invoke escape sequence.
+      
+  } else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
     Opcode = 62;
-  if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())
+  } else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {
     Opcode = 63;
+  }
 
   // Figure out which type to encode with the instruction.  Typically we want
   // the type of the first parameter, as opposed to the type of the instruction
@@ -702,6 +726,18 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
           Slots[Idx] = (Slots[Idx] << 2) | IdxId;
           if (Slots[Idx] > MaxOpSlot) MaxOpSlot = Slots[Idx];
         }
+    } else if (Opcode == 58) {
+      // If this is the escape sequence for call, emit the tailcall/cc info.
+      const CallInst &CI = cast<CallInst>(I);
+      ++NumOperands;
+      if (NumOperands < 3) {
+        Slots[NumOperands-1] = (CI.getCallingConv() << 1) | CI.isTailCall();
+        if (Slots[NumOperands-1] > MaxOpSlot)
+          MaxOpSlot = Slots[NumOperands-1];
+      }
+    } else if (Opcode == 56) {
+      // Invoke escape seq has at least 4 operands to encode.
+      ++NumOperands;
     }
 
     // Decide which instruction encoding to use.  This is determined primarily