diff options
author | Andrew Lenharth <andrewl@lenharth.org> | 2005-06-18 18:34:52 +0000 |
---|---|---|
committer | Andrew Lenharth <andrewl@lenharth.org> | 2005-06-18 18:34:52 +0000 |
commit | 558bc88a00930fce283b240b7c9555f649a18f1b (patch) | |
tree | cb2953e86c8a44260ab9f896e694fd77b19b9ad7 /lib/Bytecode | |
parent | f5428213853bae45247fe6da711ff20954d73dbd (diff) |
core changes for varargs
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22254 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bytecode')
-rw-r--r-- | lib/Bytecode/Reader/Reader.cpp | 39 | ||||
-rw-r--r-- | lib/Bytecode/Reader/ReaderWrappers.cpp | 101 | ||||
-rw-r--r-- | lib/Bytecode/Writer/SlotCalculator.cpp | 6 | ||||
-rw-r--r-- | lib/Bytecode/Writer/Writer.cpp | 11 |
4 files changed, 135 insertions, 22 deletions
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 7e5bed6989..d730ca256a 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -658,10 +658,43 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, Result = new VAArgInst(getValue(iType, Oprnds[0]), getSanitizedType(Oprnds[1])); break; - case Instruction::VANext: - Result = new VANextInst(getValue(iType, Oprnds[0]), - getSanitizedType(Oprnds[1])); + case 32: { //VANext_old + const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); + Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + + //b = vanext a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //tmp = vaarg foo, t + //b = load foo + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix"); + BB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, getValue(iType, Oprnds[0])); + BB->getInstList().push_back(bar); + BB->getInstList().push_back(new StoreInst(bar, foo)); + Instruction* tmp = new VAArgInst(foo, getSanitizedType(Oprnds[1])); + BB->getInstList().push_back(tmp); + Result = new LoadInst(foo); break; + } + case 33: { //VAArg_old + const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); + Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + + //b = vaarg a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //b = vaarg foo, t + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix"); + BB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, getValue(iType, Oprnds[0])); + BB->getInstList().push_back(bar); + BB->getInstList().push_back(new StoreInst(bar, foo)); + Result = new VAArgInst(foo, getSanitizedType(Oprnds[1])); + break; + } case Instruction::Cast: Result = new CastInst(getValue(iType, Oprnds[0]), getSanitizedType(Oprnds[1])); diff --git a/lib/Bytecode/Reader/ReaderWrappers.cpp b/lib/Bytecode/Reader/ReaderWrappers.cpp index 6823936209..8d1f384986 100644 --- a/lib/Bytecode/Reader/ReaderWrappers.cpp +++ b/lib/Bytecode/Reader/ReaderWrappers.cpp @@ -149,6 +149,100 @@ BytecodeStdinReader::BytecodeStdinReader( BytecodeHandler* H ) } //===----------------------------------------------------------------------===// +// Varargs transmogrification code... +// + +// CheckVarargs - This is used to automatically translate old-style varargs to +// new style varargs for backwards compatibility. +static ModuleProvider* CheckVarargs(ModuleProvider* MP) { + Module* M = MP->getModule(); + + // check to see if va_start takes arguements... + Function* F = M->getNamedFunction("llvm.va_start"); + if(F == 0) return MP; //No varargs use, just return. + + if (F->getFunctionType()->getNumParams() == 1) + return MP; // Modern varargs processing, just return. + + // If we get to this point, we know that we have an old-style module. + // Materialize the whole thing to perform the rewriting. + MP->materializeModule(); + + if(Function* F = M->getNamedFunction("llvm.va_start")) { + assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!"); + + //foo = va_start() + // -> + //bar = alloca typeof(foo) + //va_start(bar) + //foo = load bar + + 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_start", + RetTy, ArgTyPtr, 0); + + for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) + if (CallInst* CI = dyn_cast<CallInst>(*I++)) { + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI); + new CallInst(NF, bar, "", CI); + Value* foo = new LoadInst(bar, "vastart.fix.2", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + F->setName(""); + } + + if(Function* F = M->getNamedFunction("llvm.va_end")) { + assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!"); + //vaend foo + // -> + //bar = alloca 1 of typeof(foo) + //vaend bar + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getParamType(0); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = M->getOrInsertFunction("llvm.va_end", + RetTy, ArgTyPtr, 0); + + for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) + if (CallInst* CI = dyn_cast<CallInst>(*I++)) { + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); + new CallInst(NF, bar, "", CI); + CI->getParent()->getInstList().erase(CI); + } + F->setName(""); + } + + if(Function* F = M->getNamedFunction("llvm.va_copy")) { + assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!"); + //foo = vacopy(bar) + // -> + //a = alloca 1 of typeof(foo) + //vacopy(a, bar) + //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); + + 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); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + F->setName(""); + } + return MP; +} + +//===----------------------------------------------------------------------===// // Wrapper functions //===----------------------------------------------------------------------===// @@ -159,7 +253,8 @@ llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer, unsigned Length, const std::string &ModuleID, BytecodeHandler* H ) { - return new BytecodeBufferReader(Buffer, Length, ModuleID, H); + return CheckVarargs( + new BytecodeBufferReader(Buffer, Length, ModuleID, H)); } /// ParseBytecodeBuffer - Parse a given bytecode buffer @@ -182,9 +277,9 @@ Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length, ModuleProvider *llvm::getBytecodeModuleProvider(const std::string &Filename, BytecodeHandler* H) { if (Filename != std::string("-")) // Read from a file... - return new BytecodeFileReader(Filename,H); + return CheckVarargs(new BytecodeFileReader(Filename,H)); else // Read from stdin - return new BytecodeStdinReader(H); + return CheckVarargs(new BytecodeStdinReader(H)); } /// ParseBytecodeFile - Parse the given bytecode file diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp index fbeb50c03a..c6aba09fe5 100644 --- a/lib/Bytecode/Writer/SlotCalculator.cpp +++ b/lib/Bytecode/Writer/SlotCalculator.cpp @@ -187,8 +187,6 @@ void SlotCalculator::processModule() { !isa<GlobalValue>(I->getOperand(op))) getOrCreateSlot(I->getOperand(op)); getOrCreateSlot(I->getType()); - if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I)) - getOrCreateSlot(VAN->getArgType()); } processSymbolTableConstants(&F->getSymbolTable()); } @@ -320,8 +318,6 @@ void SlotCalculator::incorporateFunction(const Function *F) { getOrCreateSlot(BB); for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { getOrCreateSlot(I); - if (const VANextInst *VAN = dyn_cast<VANextInst>(I)) - getOrCreateSlot(VAN->getArgType()); } } @@ -472,8 +468,6 @@ void SlotCalculator::buildCompactionTable(const Function *F) { for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) if (isa<Constant>(I->getOperand(op))) getOrCreateCompactionTableSlot(I->getOperand(op)); - if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I)) - getOrCreateCompactionTableSlot(VAN->getArgType()); } // Do the types in the symbol table diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index fb5a1aa603..90cfa96462 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -439,7 +439,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, output_typeid(Type); // Result type unsigned NumArgs = I->getNumOperands(); - output_vbr(NumArgs + (isa<CastInst>(I) || isa<VANextInst>(I) || + output_vbr(NumArgs + (isa<CastInst>(I) || isa<VAArgInst>(I) || Opcode == 56 || Opcode == 58)); if (!isa<GetElementPtrInst>(&I)) { @@ -453,10 +453,6 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Cast return type unknown?"); output_typeid((unsigned)Slot); - } else if (const VANextInst *VAI = dyn_cast<VANextInst>(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 @@ -704,11 +700,6 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { assert(Slots[1] != ~0U && "Cast return type unknown?"); if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; NumOperands++; - } else if (const VANextInst *VANI = dyn_cast<VANextInst>(&I)) { - Slots[1] = Table.getSlot(VANI->getArgType()); - assert(Slots[1] != ~0U && "va_next return type unknown?"); - if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; - NumOperands++; } else if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) { // We need to encode the type of sequential type indices into their slot # unsigned Idx = 1; |