mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-02 16:56:50 +00:00
encode calling conventions for call/invoke instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21751 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6dc7e6833b
commit
dee199fe82
@ -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<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));
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user