class SlotCalculator {
const Module *TheModule;
- /// BuildBytecodeInfo - If true, this is the creating information for the
- /// bytecode writer, if false, we are building information for the assembly
- /// emitter. The assembly emitter doesn't need named objects numbered, among
- /// other differences.
- bool BuildBytecodeInfo;
-
typedef std::vector<const Value*> TypePlane;
std::vector<TypePlane> Table;
std::map<const Value*, unsigned> NodeMap;
SlotCalculator(const SlotCalculator &); // DO NOT IMPLEMENT
void operator=(const SlotCalculator &); // DO NOT IMPLEMENT
public:
- SlotCalculator(const Module *M, bool BuildBytecodeInfo);
+ SlotCalculator(const Module *M );
// Start out in incorp state
- SlotCalculator(const Function *F, bool BuildBytecodeInfo);
+ SlotCalculator(const Function *F );
/// getSlot - Return the slot number of the specified value in it's type
/// plane. This returns < 0 on error!
#include "llvm/Value.h"
#include <iostream>
+namespace {
+class SlotMachine; // Internal private class
+}
+
namespace llvm {
class Module;
class PointerType;
-class SlotCalculator;
class AssemblyWriter; // Internal private class
class CachedWriter {
AssemblyWriter *AW;
- SlotCalculator *SC;
+ SlotMachine *SC;
bool SymbolicTypes;
std::ostream *Out;
#define SC_DEBUG(X)
#endif
-SlotCalculator::SlotCalculator(const Module *M, bool buildBytecodeInfo) {
- BuildBytecodeInfo = buildBytecodeInfo;
+SlotCalculator::SlotCalculator(const Module *M ) {
ModuleContainsAllFunctionConstants = false;
TheModule = M;
processModule();
}
-SlotCalculator::SlotCalculator(const Function *M, bool buildBytecodeInfo) {
- BuildBytecodeInfo = buildBytecodeInfo;
+SlotCalculator::SlotCalculator(const Function *M ) {
ModuleContainsAllFunctionConstants = false;
TheModule = M ? M->getParent() : 0;
// that contain constant strings so that the strings occur at the start of the
// plane, not somewhere in the middle.
//
- if (BuildBytecodeInfo) {
- TypePlane &Types = Table[Type::TypeTyID];
- for (unsigned plane = 0, e = Table.size(); plane != e; ++plane) {
- if (const ArrayType *AT = dyn_cast<ArrayType>(Types[plane]))
- if (AT->getElementType() == Type::SByteTy ||
- AT->getElementType() == Type::UByteTy) {
- TypePlane &Plane = Table[plane];
- unsigned FirstNonStringID = 0;
- for (unsigned i = 0, e = Plane.size(); i != e; ++i)
- if (isa<ConstantAggregateZero>(Plane[i]) ||
- cast<ConstantArray>(Plane[i])->isString()) {
- // Check to see if we have to shuffle this string around. If not,
- // don't do anything.
- if (i != FirstNonStringID) {
- // Swap the plane entries....
- std::swap(Plane[i], Plane[FirstNonStringID]);
-
- // Keep the NodeMap up to date.
- NodeMap[Plane[i]] = i;
- NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
- }
- ++FirstNonStringID;
- }
- }
- }
+ TypePlane &Types = Table[Type::TypeTyID];
+ for (unsigned plane = 0, e = Table.size(); plane != e; ++plane) {
+ if (const ArrayType *AT = dyn_cast<ArrayType>(Types[plane]))
+ if (AT->getElementType() == Type::SByteTy ||
+ AT->getElementType() == Type::UByteTy) {
+ TypePlane &Plane = Table[plane];
+ unsigned FirstNonStringID = 0;
+ for (unsigned i = 0, e = Plane.size(); i != e; ++i)
+ if (isa<ConstantAggregateZero>(Plane[i]) ||
+ cast<ConstantArray>(Plane[i])->isString()) {
+ // Check to see if we have to shuffle this string around. If not,
+ // don't do anything.
+ if (i != FirstNonStringID) {
+ // Swap the plane entries....
+ std::swap(Plane[i], Plane[FirstNonStringID]);
+
+ // Keep the NodeMap up to date.
+ NodeMap[Plane[i]] = i;
+ NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
+ }
+ ++FirstNonStringID;
+ }
+ }
}
// If we are emitting a bytecode file, scan all of the functions for their
// the fly. For now, however, it is unconditionally enabled when building
// bytecode information.
//
- if (BuildBytecodeInfo) {
- ModuleContainsAllFunctionConstants = true;
-
- 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)))
- getOrCreateSlot(I->getOperand(op));
- getOrCreateSlot(I->getType());
- if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I))
- getOrCreateSlot(VAN->getArgType());
- }
- processSymbolTableConstants(&F->getSymbolTable());
+ ModuleContainsAllFunctionConstants = true;
+
+ 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)))
+ getOrCreateSlot(I->getOperand(op));
+ getOrCreateSlot(I->getType());
+ if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I))
+ getOrCreateSlot(VAN->getArgType());
}
+ processSymbolTableConstants(&F->getSymbolTable());
}
// Insert constants that are named at module level into the slot pool so that
// the module symbol table can refer to them...
- //
- if (BuildBytecodeInfo) {
- SC_DEBUG("Inserting SymbolTable values:\n");
- processSymbolTable(&TheModule->getSymbolTable());
- }
+ SC_DEBUG("Inserting SymbolTable values:\n");
+ processSymbolTable(&TheModule->getSymbolTable());
// Now that we have collected together all of the information relevant to the
// module, compactify the type table if it is particularly big and outputting
// all non-value types are pushed to the end of the type table, giving nice
// low numbers to the types that can be used by instructions, thus reducing
// the amount of explodage we suffer.
- if (BuildBytecodeInfo && Table[Type::TypeTyID].size() >= 64) {
+ if (Table[Type::TypeTyID].size() >= 64) {
// Scan through the type table moving value types to the start of the table.
TypePlane *Types = &Table[Type::TypeTyID];
unsigned FirstNonValueTypeID = 0;
SC_DEBUG("begin processFunction!\n");
// If we emitted all of the function constants, build a compaction table.
- if (BuildBytecodeInfo && ModuleContainsAllFunctionConstants)
+ if ( ModuleContainsAllFunctionConstants)
buildCompactionTable(F);
// Update the ModuleLevel entries to be accurate.
for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
getOrCreateSlot(I);
- if (BuildBytecodeInfo && // Assembly writer does not need this!
- !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
assert(CompactionNodeMap.empty() &&
"All needed constants should be in the compaction map already!");
- // If we are emitting a bytecode file, do not index the characters that
- // make up constant strings. We emit constant strings as special
- // entities that don't require their individual characters to be emitted.
- if (!BuildBytecodeInfo || !isa<ConstantArray>(C) ||
- !cast<ConstantArray>(C)->isString()) {
+ // Do not index the characters that make up constant strings. We emit
+ // constant strings as special entities that don't require their
+ // individual characters to be emitted.
+ if (!isa<ConstantArray>(C) || !cast<ConstantArray>(C)->isString()) {
// This makes sure that if a constant has uses (for example an array of
// const ints), that they are inserted also.
//
// do need slot numbers so that we can keep track of where other values land.
//
if (!dontIgnore) // Don't ignore nonignorables!
- if (D->getType() == Type::VoidTy || // Ignore void type nodes
- (!BuildBytecodeInfo && // Ignore named and constants
- (D->hasName() || isa<Constant>(D)) && !isa<Type>(D))) {
+ if (D->getType() == Type::VoidTy ) { // Ignore void type nodes
SC_DEBUG("ignored value " << *D << "\n");
return -1; // We do need types unconditionally though
}
// If this is the first value to get inserted into the type plane, make sure
// to insert the implicit null value...
- if (Table[Ty].empty() && BuildBytecodeInfo && hasNullValue(Ty)) {
+ if (Table[Ty].empty() && hasNullValue(Ty)) {
Value *ZeroInitializer = Constant::getNullValue(Typ);
// If we are pushing zeroinit, it will be handled below.
class SlotCalculator {
const Module *TheModule;
- /// BuildBytecodeInfo - If true, this is the creating information for the
- /// bytecode writer, if false, we are building information for the assembly
- /// emitter. The assembly emitter doesn't need named objects numbered, among
- /// other differences.
- bool BuildBytecodeInfo;
-
typedef std::vector<const Value*> TypePlane;
std::vector<TypePlane> Table;
std::map<const Value*, unsigned> NodeMap;
SlotCalculator(const SlotCalculator &); // DO NOT IMPLEMENT
void operator=(const SlotCalculator &); // DO NOT IMPLEMENT
public:
- SlotCalculator(const Module *M, bool BuildBytecodeInfo);
+ SlotCalculator(const Module *M );
// Start out in incorp state
- SlotCalculator(const Function *F, bool BuildBytecodeInfo);
+ SlotCalculator(const Function *F );
/// getSlot - Return the slot number of the specified value in it's type
/// plane. This returns < 0 on error!
BytesWritten("bytecodewriter", "Number of bytecode bytes written");
BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
- : Out(o), Table(M, true) {
+ : Out(o), Table(M) {
// Emit the signature...
static const unsigned char *Sig = (const unsigned char*)"llvm";
#define SC_DEBUG(X)
#endif
-SlotCalculator::SlotCalculator(const Module *M, bool buildBytecodeInfo) {
- BuildBytecodeInfo = buildBytecodeInfo;
+SlotCalculator::SlotCalculator(const Module *M ) {
ModuleContainsAllFunctionConstants = false;
TheModule = M;
processModule();
}
-SlotCalculator::SlotCalculator(const Function *M, bool buildBytecodeInfo) {
- BuildBytecodeInfo = buildBytecodeInfo;
+SlotCalculator::SlotCalculator(const Function *M ) {
ModuleContainsAllFunctionConstants = false;
TheModule = M ? M->getParent() : 0;
// that contain constant strings so that the strings occur at the start of the
// plane, not somewhere in the middle.
//
- if (BuildBytecodeInfo) {
- TypePlane &Types = Table[Type::TypeTyID];
- for (unsigned plane = 0, e = Table.size(); plane != e; ++plane) {
- if (const ArrayType *AT = dyn_cast<ArrayType>(Types[plane]))
- if (AT->getElementType() == Type::SByteTy ||
- AT->getElementType() == Type::UByteTy) {
- TypePlane &Plane = Table[plane];
- unsigned FirstNonStringID = 0;
- for (unsigned i = 0, e = Plane.size(); i != e; ++i)
- if (isa<ConstantAggregateZero>(Plane[i]) ||
- cast<ConstantArray>(Plane[i])->isString()) {
- // Check to see if we have to shuffle this string around. If not,
- // don't do anything.
- if (i != FirstNonStringID) {
- // Swap the plane entries....
- std::swap(Plane[i], Plane[FirstNonStringID]);
-
- // Keep the NodeMap up to date.
- NodeMap[Plane[i]] = i;
- NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
- }
- ++FirstNonStringID;
- }
- }
- }
+ TypePlane &Types = Table[Type::TypeTyID];
+ for (unsigned plane = 0, e = Table.size(); plane != e; ++plane) {
+ if (const ArrayType *AT = dyn_cast<ArrayType>(Types[plane]))
+ if (AT->getElementType() == Type::SByteTy ||
+ AT->getElementType() == Type::UByteTy) {
+ TypePlane &Plane = Table[plane];
+ unsigned FirstNonStringID = 0;
+ for (unsigned i = 0, e = Plane.size(); i != e; ++i)
+ if (isa<ConstantAggregateZero>(Plane[i]) ||
+ cast<ConstantArray>(Plane[i])->isString()) {
+ // Check to see if we have to shuffle this string around. If not,
+ // don't do anything.
+ if (i != FirstNonStringID) {
+ // Swap the plane entries....
+ std::swap(Plane[i], Plane[FirstNonStringID]);
+
+ // Keep the NodeMap up to date.
+ NodeMap[Plane[i]] = i;
+ NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
+ }
+ ++FirstNonStringID;
+ }
+ }
}
// If we are emitting a bytecode file, scan all of the functions for their
// the fly. For now, however, it is unconditionally enabled when building
// bytecode information.
//
- if (BuildBytecodeInfo) {
- ModuleContainsAllFunctionConstants = true;
-
- 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)))
- getOrCreateSlot(I->getOperand(op));
- getOrCreateSlot(I->getType());
- if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I))
- getOrCreateSlot(VAN->getArgType());
- }
- processSymbolTableConstants(&F->getSymbolTable());
+ ModuleContainsAllFunctionConstants = true;
+
+ 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)))
+ getOrCreateSlot(I->getOperand(op));
+ getOrCreateSlot(I->getType());
+ if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I))
+ getOrCreateSlot(VAN->getArgType());
}
+ processSymbolTableConstants(&F->getSymbolTable());
}
// Insert constants that are named at module level into the slot pool so that
// the module symbol table can refer to them...
- //
- if (BuildBytecodeInfo) {
- SC_DEBUG("Inserting SymbolTable values:\n");
- processSymbolTable(&TheModule->getSymbolTable());
- }
+ SC_DEBUG("Inserting SymbolTable values:\n");
+ processSymbolTable(&TheModule->getSymbolTable());
// Now that we have collected together all of the information relevant to the
// module, compactify the type table if it is particularly big and outputting
// all non-value types are pushed to the end of the type table, giving nice
// low numbers to the types that can be used by instructions, thus reducing
// the amount of explodage we suffer.
- if (BuildBytecodeInfo && Table[Type::TypeTyID].size() >= 64) {
+ if (Table[Type::TypeTyID].size() >= 64) {
// Scan through the type table moving value types to the start of the table.
TypePlane *Types = &Table[Type::TypeTyID];
unsigned FirstNonValueTypeID = 0;
SC_DEBUG("begin processFunction!\n");
// If we emitted all of the function constants, build a compaction table.
- if (BuildBytecodeInfo && ModuleContainsAllFunctionConstants)
+ if ( ModuleContainsAllFunctionConstants)
buildCompactionTable(F);
// Update the ModuleLevel entries to be accurate.
for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
getOrCreateSlot(I);
- if (BuildBytecodeInfo && // Assembly writer does not need this!
- !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
assert(CompactionNodeMap.empty() &&
"All needed constants should be in the compaction map already!");
- // If we are emitting a bytecode file, do not index the characters that
- // make up constant strings. We emit constant strings as special
- // entities that don't require their individual characters to be emitted.
- if (!BuildBytecodeInfo || !isa<ConstantArray>(C) ||
- !cast<ConstantArray>(C)->isString()) {
+ // Do not index the characters that make up constant strings. We emit
+ // constant strings as special entities that don't require their
+ // individual characters to be emitted.
+ if (!isa<ConstantArray>(C) || !cast<ConstantArray>(C)->isString()) {
// This makes sure that if a constant has uses (for example an array of
// const ints), that they are inserted also.
//
// do need slot numbers so that we can keep track of where other values land.
//
if (!dontIgnore) // Don't ignore nonignorables!
- if (D->getType() == Type::VoidTy || // Ignore void type nodes
- (!BuildBytecodeInfo && // Ignore named and constants
- (D->hasName() || isa<Constant>(D)) && !isa<Type>(D))) {
+ if (D->getType() == Type::VoidTy ) { // Ignore void type nodes
SC_DEBUG("ignored value " << *D << "\n");
return -1; // We do need types unconditionally though
}
// If this is the first value to get inserted into the type plane, make sure
// to insert the implicit null value...
- if (Table[Ty].empty() && BuildBytecodeInfo && hasNullValue(Ty)) {
+ if (Table[Ty].empty() && hasNullValue(Ty)) {
Value *ZeroInitializer = Constant::getNullValue(Typ);
// If we are pushing zeroinit, it will be handled below.