From dee199fe82f9cc10d61fe6e8f9924b8837231e67 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 6 May 2005 22:34:01 +0000 Subject: [PATCH] encode calling conventions for call/invoke instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21751 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bytecode/Reader/Reader.cpp | 44 +++++++++++++++++++++++++----- lib/Bytecode/Writer/Writer.cpp | 50 +++++++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 8e46083082f..e48f64178c1 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -19,11 +19,12 @@ #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 &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(F->getType()); if (PTy == 0) error("Call to non function pointer value!"); @@ -737,6 +747,13 @@ void BytecodeReader::ParseInstruction(std::vector &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 &Oprnds, } Result = new CallInst(F, Params); - if (Opcode == 61) cast(Result)->setTailCall(true); + if (isTailCall) cast(Result)->setTailCall(); + if (CallingConv) cast(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 &Oprnds, std::vector 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 &Oprnds, } Result = new InvokeInst(F, Normal, Except, Params); + if (CallingConv) cast(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)); } diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 4cf4cf5a97d..81c86d6ffab 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -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] // @@ -439,7 +440,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, unsigned NumArgs = I->getNumOperands(); output_vbr(NumArgs + (isa(I) || isa(I) || - isa(I))); + isa(I) || Opcode == 56 || Opcode == 58)); if (!isa(&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(I)->getCallingConv()); + } else if (Opcode == 58) { // Call escape sequence + output_vbr((cast(I)->getCallingConv() << 1) | + cast(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(I) && cast(I).isTailCall()) - Opcode = 61; - if (isa(I) && cast(I).isVolatile()) + if (const CallInst *CI = dyn_cast(&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(&I)) { + if (II->getCallingConv() == CallingConv::Fast) + Opcode = 57; // FastCC invoke. + else if (II->getCallingConv() != CallingConv::C) + Opcode = 56; // Invoke escape sequence. + + } else if (isa(I) && cast(I).isVolatile()) { Opcode = 62; - if (isa(I) && cast(I).isVolatile()) + } else if (isa(I) && cast(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(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