diff options
-rw-r--r-- | lib/Bytecode/Reader/Reader.cpp | 39 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Reader.h | 4 | ||||
-rw-r--r-- | lib/Bytecode/Writer/SlotCalculator.cpp | 25 | ||||
-rw-r--r-- | lib/Bytecode/Writer/SlotCalculator.h | 14 | ||||
-rw-r--r-- | lib/Bytecode/Writer/Writer.cpp | 22 | ||||
-rw-r--r-- | lib/Bytecode/Writer/WriterInternals.h | 4 |
6 files changed, 74 insertions, 34 deletions
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index d2660e3fab..d142aacfa5 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -22,6 +22,7 @@ #include "llvm/BasicBlock.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/SymbolTable.h" #include "llvm/Bytecode/Format.h" @@ -1404,7 +1405,7 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){ } /// Parse a single constant value -Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { +Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) { // We must check for a ConstantExpr before switching by type because // a ConstantExpr can be of any type, and has no explicit value. // @@ -1412,11 +1413,32 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { unsigned isExprNumArgs = read_vbr_uint(); if (isExprNumArgs) { - // 'undef' is encoded with 'exprnumargs' == 1. - if (!hasNoUndefValue) - if (--isExprNumArgs == 0) + if (!hasNoUndefValue) { + // 'undef' is encoded with 'exprnumargs' == 1. + if (isExprNumArgs == 1) return UndefValue::get(getType(TypeID)); + // Inline asm is encoded with exprnumargs == ~0U. + if (isExprNumArgs == ~0U) { + std::string AsmStr = read_str(); + std::string ConstraintStr = read_str(); + unsigned Flags = read_vbr_uint(); + + const PointerType *PTy = dyn_cast<PointerType>(getType(TypeID)); + const FunctionType *FTy = + PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0; + + if (!FTy || !InlineAsm::Verify(FTy, ConstraintStr)) + error("Invalid constraints for inline asm"); + if (Flags & ~1U) + error("Invalid flags for inline asm"); + bool HasSideEffects = Flags & 1; + return InlineAsm::get(FTy, AsmStr, ConstraintStr, HasSideEffects); + } + + --isExprNumArgs; + } + // FIXME: Encoding of constant exprs could be much more compact! std::vector<Constant*> ArgVec; ArgVec.reserve(isExprNumArgs); @@ -1695,9 +1717,9 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab, ParseStringConstants(NumEntries, Tab); } else { for (unsigned i = 0; i < NumEntries; ++i) { - Constant *C = ParseConstantValue(Typ); - assert(C && "ParseConstantValue returned NULL!"); - unsigned Slot = insertValue(C, Typ, Tab); + Value *V = ParseConstantPoolValue(Typ); + assert(V && "ParseConstantPoolValue returned NULL!"); + unsigned Slot = insertValue(V, Typ, Tab); // If we are reading a function constant table, make sure that we adjust // the slot number to be the real global constant number. @@ -1705,7 +1727,8 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab, if (&Tab != &ModuleValues && Typ < ModuleValues.size() && ModuleValues[Typ]) Slot += ModuleValues[Typ]->size(); - ResolveReferencesToConstant(C, Typ, Slot); + if (Constant *C = dyn_cast<Constant>(V)) + ResolveReferencesToConstant(C, Typ, Slot); } } } diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h index 25410838d3..21eb8462fb 100644 --- a/lib/Bytecode/Reader/Reader.h +++ b/lib/Bytecode/Reader/Reader.h @@ -229,8 +229,8 @@ protected: void ParseConstantPool(ValueTable& Values, TypeListTy& Types, bool isFunction); - /// @brief Parse a single constant value - Constant* ParseConstantValue(unsigned TypeID); + /// @brief Parse a single constant pool value + Value *ParseConstantPoolValue(unsigned TypeID); /// @brief Parse a block of types constants void ParseTypes(TypeListTy &Tab, unsigned NumEntries); diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp index c6aba09fe5..26bd1be8f6 100644 --- a/lib/Bytecode/Writer/SlotCalculator.cpp +++ b/lib/Bytecode/Writer/SlotCalculator.cpp @@ -18,6 +18,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" @@ -27,7 +28,6 @@ #include "llvm/ADT/STLExtras.h" #include <algorithm> #include <functional> - using namespace llvm; #if 0 @@ -181,11 +181,13 @@ void SlotCalculator::processModule() { SC_DEBUG("Inserting function constants:\n"); for (Module::const_iterator F = TheModule->begin(), E = TheModule->end(); F != E; ++F) { - for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I){ - for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) - if (isa<Constant>(I->getOperand(op)) && - !isa<GlobalValue>(I->getOperand(op))) - getOrCreateSlot(I->getOperand(op)); + for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { + for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); + OI != E; ++OI) { + if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) || + isa<InlineAsm>(*OI)) + getOrCreateSlot(*OI); + } getOrCreateSlot(I->getType()); } processSymbolTableConstants(&F->getSymbolTable()); @@ -286,7 +288,7 @@ void SlotCalculator::incorporateFunction(const Function *F) { for(Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) getOrCreateSlot(I); - if ( !ModuleContainsAllFunctionConstants ) { + if (!ModuleContainsAllFunctionConstants) { // Iterate over all of the instructions in the function, looking for // constant values that are referenced. Add these to the value pools // before any nonconstant values. This will be turned into the constant @@ -295,12 +297,9 @@ void SlotCalculator::incorporateFunction(const Function *F) { // Emit all of the constants that are being used by the instructions in // the function... - constant_iterator CI = constant_begin(F); - constant_iterator CE = constant_end(F); - while ( CI != CE ) { - this->getOrCreateSlot(*CI); - ++CI; - } + for (constant_iterator CI = constant_begin(F), CE = constant_end(F); + CI != CE; ++CI) + getOrCreateSlot(*CI); // If there is a symbol table, it is possible that the user has names for // constants that are not being used. In this case, we will have problems diff --git a/lib/Bytecode/Writer/SlotCalculator.h b/lib/Bytecode/Writer/SlotCalculator.h index 63927ca814..e88a88f726 100644 --- a/lib/Bytecode/Writer/SlotCalculator.h +++ b/lib/Bytecode/Writer/SlotCalculator.h @@ -74,9 +74,9 @@ class SlotCalculator { SlotCalculator(const SlotCalculator &); // DO NOT IMPLEMENT void operator=(const SlotCalculator &); // DO NOT IMPLEMENT public: - SlotCalculator(const Module *M ); + SlotCalculator(const Module *M); // Start out in incorp state - SlotCalculator(const Function *F ); + SlotCalculator(const Function *F); /// getSlot - Return the slot number of the specified value in it's type /// plane. This returns < 0 on error! @@ -146,19 +146,19 @@ private: // they haven't been inserted already, they get inserted, otherwise // they are ignored. // - int getOrCreateSlot(const Value *D); - int getOrCreateSlot(const Type* T); + int getOrCreateSlot(const Value *V); + int getOrCreateSlot(const Type *T); // insertValue - Insert a value into the value table... Return the // slot that it occupies, or -1 if the declaration is to be ignored // because of the IgnoreNamedNodes flag. // int insertValue(const Value *D, bool dontIgnore = false); - int insertType(const Type* T, bool dontIgnore = false ); + int insertType(const Type *T, bool dontIgnore = false); // doInsertValue - Small helper function to be called only be insertVal. - int doInsertValue(const Value *D); - int doInsertType(const Type*T); + int doInsertValue(const Value *V); + int doInsertType(const Type *T); // processModule - Process all of the module level function declarations and // types that are available. diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index bfbce91c56..80abcacee9 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -22,6 +22,7 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" @@ -389,6 +390,19 @@ void BytecodeWriter::outputConstant(const Constant *CPV) { return; } +/// outputInlineAsm - InlineAsm's get emitted to the constant pool, so they can +/// be shared by multiple uses. +void BytecodeWriter::outputInlineAsm(const InlineAsm *IA) { + // Output a marker, so we know when we have one one parsing the constant pool. + // Note that this encoding is 5 bytes: not very efficient for a marker. Since + // unique inline asms are rare, this should hardly matter. + output_vbr(~0U); + + output(IA->getAsmString()); + output(IA->getConstraintString()); + output_vbr(unsigned(IA->hasSideEffects())); +} + void BytecodeWriter::outputConstantStrings() { SlotCalculator::string_iterator I = Table.string_begin(); SlotCalculator::string_iterator E = Table.string_end(); @@ -847,7 +861,8 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*> /*empty*/; unsigned NC = ValNo; // Number of constants - for (; NC < Plane.size() && (isa<Constant>(Plane[NC])); NC++) + for (; NC < Plane.size() && (isa<Constant>(Plane[NC]) || + isa<InlineAsm>(Plane[NC])); NC++) /*empty*/; NC -= ValNo; // Convert from index into count if (NC == 0) return; // Skip empty type planes... @@ -866,9 +881,10 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*> for (unsigned i = ValNo; i < ValNo+NC; ++i) { const Value *V = Plane[i]; - if (const Constant *C = dyn_cast<Constant>(V)) { + if (const Constant *C = dyn_cast<Constant>(V)) outputConstant(C); - } + else + outputInlineAsm(cast<InlineAsm>(V)); } } diff --git a/lib/Bytecode/Writer/WriterInternals.h b/lib/Bytecode/Writer/WriterInternals.h index 15dd92db1e..f8c276e858 100644 --- a/lib/Bytecode/Writer/WriterInternals.h +++ b/lib/Bytecode/Writer/WriterInternals.h @@ -24,6 +24,7 @@ #include <vector> namespace llvm { + class InlineAsm; class BytecodeWriter { std::vector<unsigned char> &Out; @@ -68,6 +69,7 @@ private: void outputConstantsInPlane(const std::vector<const Value*> &Plane, unsigned StartNo); void outputConstant(const Constant *CPV); + void outputInlineAsm(const InlineAsm *IA); void outputType(const Type *T); /// @brief Unsigned integer output primitive @@ -88,7 +90,7 @@ private: /// @brief Signed 32-bit variable bit rate output primitive. inline void output_vbr(int i); - inline void output(const std::string &s ); + inline void output(const std::string &s); inline void output_data(const void *Ptr, const void *End); |