mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-02 13:21:43 +00:00
add bc reader/writer support for inline asm
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25621 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5f8f0e219d
commit
3bc5a60b80
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user