#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instruction.h"
-#include "llvm/iMemory.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iOther.h"
+#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h"
-#include "Support/StringExtras.h"
-#include "Support/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include <algorithm>
using namespace llvm;
-namespace {
+namespace llvm {
/// This class provides computation of slot numbers for LLVM Assembly writing.
/// @brief LLVM Assembly Writing Slot Computation.
public:
/// If you'd like to deal with a function instead of just a module, use
/// this method to get its data into the SlotMachine.
- void incorporateFunction(const Function *F) { TheFunction = F; }
+ void incorporateFunction(const Function *F) {
+ TheFunction = F;
+ FunctionProcessed = false;
+ }
/// After calling incorporateFunction, use this method to remove the
/// most recently incorporated function from the SlotMachine. This
/// @brief The function for which we are holding slot numbers
const Function* TheFunction;
+ bool FunctionProcessed;
/// @brief The TypePlanes map for the module level data
TypedPlanes mMap;
};
-}
+} // end namespace llvm
static RegisterPass<PrintModulePass>
X("printm", "Print module to stderr",PassInfo::Analysis|PassInfo::Optimization);
Result += "]";
break;
}
+ case Type::PackedTyID: {
+ const PackedType *PTy = cast<PackedType>(Ty);
+ Result += "<" + utostr(PTy->getNumElements()) + " x ";
+ calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result);
+ Result += ">";
+ break;
+ }
case Type::OpaqueTyID:
Result += "opaque";
break;
}
}
+/// @brief Internal constant writer.
static void WriteConstantInt(std::ostream &Out, const Constant *CV,
bool PrintName,
std::map<const Type *, std::string> &TypeTable,
}
Out << " }";
+ } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
+ const Type *ETy = CP->getType()->getElementType();
+ assert(CP->getNumOperands() > 0 &&
+ "Number of operands for a PackedConst must be > 0");
+ Out << '<';
+ Out << ' ';
+ printTypeInt(Out, ETy, TypeTable);
+ WriteAsOperandInternal(Out, CP->getOperand(0),
+ PrintName, TypeTable, Machine);
+ for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
+ Out << ", ";
+ printTypeInt(Out, ETy, TypeTable);
+ WriteAsOperandInternal(Out, CP->getOperand(i), PrintName,
+ TypeTable, Machine);
+ }
+ Out << " >";
} else if (isa<ConstantPointerNull>(CV)) {
Out << "null";
- } else if (const ConstantPointerRef *PR = dyn_cast<ConstantPointerRef>(CV)) {
- WriteAsOperandInternal(Out, PR->getValue(), true, TypeTable, Machine);
+ } else if (isa<UndefValue>(CV)) {
+ Out << "undef";
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
Out << CE->getOpcodeName() << " (";
std::map<const Type*, std::string> &TypeTable,
SlotMachine *Machine) {
Out << ' ';
- if (PrintName && V->hasName()) {
+ if ((PrintName || isa<GlobalValue>(V)) && V->hasName())
Out << getLLVMName(V->getName());
- } else {
- if (const Constant *CV = dyn_cast<Constant>(V)) {
+ else {
+ const Constant *CV = dyn_cast<Constant>(V);
+ if (CV && !isa<GlobalValue>(CV))
WriteConstantInt(Out, CV, PrintName, TypeTable, Machine);
- } else {
+ else {
int Slot;
if (Machine) {
Slot = Machine->getSlot(V);
const Module* getModule() { return TheModule; }
-private :
+private:
void printModule(const Module *M);
void printSymbolTable(const SymbolTable &ST);
void printConstant(const Constant *CPV);
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Out << '[' << ATy->getNumElements() << " x ";
printType(ATy->getElementType()) << ']';
- } else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
+ } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
+ Out << '<' << PTy->getNumElements() << " x ";
+ printType(PTy->getElementType()) << '>';
+ }
+ else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
Out << "opaque";
} else {
if (!Ty->isPrimitiveType())
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
bool PrintName) {
+ assert(Operand != 0 && "Illegal Operand");
if (PrintType) { Out << ' '; printType(Operand->getType()); }
WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Machine);
}
case Module::Pointer64: Out << "target pointersize = 64\n"; break;
case Module::AnyPointerSize: break;
}
+ if (!M->getTargetTriple().empty())
+ Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
- // Loop over the symbol table, emitting all named constants...
+ // Loop over the dependent libraries and emit them.
+ Module::lib_iterator LI = M->lib_begin();
+ Module::lib_iterator LE = M->lib_end();
+ if (LI != LE) {
+ Out << "deplibs = [ ";
+ while (LI != LE) {
+ Out << '"' << *LI << '"';
+ ++LI;
+ if (LI != LE)
+ Out << ", ";
+ }
+ Out << " ]\n";
+ }
+
+ // Loop over the symbol table, emitting all named constants.
printSymbolTable(M->getSymbolTable());
for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
Out << "\nimplementation ; Functions:\n";
- // Output all of the functions...
+ // Output all of the functions.
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
printFunction(I);
}
case GlobalValue::WeakLinkage: Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break;
case GlobalValue::ExternalLinkage: break;
+ case GlobalValue::GhostLinkage:
+ std::cerr << "GhostLinkage not allowed in AsmWriter!\n";
+ abort();
}
Out << (GV->isConstant() ? "constant " : "global ");
printType(GV->getType()->getElementType());
- if (GV->hasInitializer())
- writeOperand(GV->getInitializer(), false, false);
+ if (GV->hasInitializer()) {
+ Constant* C = cast<Constant>(GV->getInitializer());
+ assert(C && "GlobalVar initializer isn't constant?");
+ writeOperand(GV->getInitializer(), false, isa<GlobalValue>(C));
+ }
printInfoComment(*GV);
Out << "\n";
SymbolTable::value_const_iterator VE = ST.value_end(PI->first);
for (; VI != VE; ++VI) {
- const Value *V = VI->second;
- if (const Constant *CPV = dyn_cast<Constant>(V)) {
+ const Value* V = VI->second;
+ const Constant *CPV = dyn_cast<Constant>(V) ;
+ if (CPV && !isa<GlobalValue>(V)) {
printConstant(CPV);
}
}
case GlobalValue::WeakLinkage: Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break;
case GlobalValue::ExternalLinkage: break;
+ case GlobalValue::GhostLinkage:
+ std::cerr << "GhostLinkage not allowed in AsmWriter!\n";
+ abort();
}
printType(F->getReturnType()) << ' ';
void Constant::print(std::ostream &o) const {
if (this == 0) { o << "<null> constant value\n"; return; }
- // Handle CPR's special, because they have context information...
- if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(this)) {
- CPR->getValue()->print(o); // Print as a global value, with context info.
- return;
- }
-
o << ' ' << getType()->getDescription() << ' ';
std::map<const Type *, std::string> TypeTable;
delete SC;
}
-CachedWriter &CachedWriter::operator<<(const Value *V) {
+CachedWriter &CachedWriter::operator<<(const Value &V) {
assert(AW && SC && "CachedWriter does not have a current module!");
- if (const Instruction *I = dyn_cast<Instruction>(V))
+ if (const Instruction *I = dyn_cast<Instruction>(&V))
AW->write(I);
- else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ else if (const BasicBlock *BB = dyn_cast<BasicBlock>(&V))
AW->write(BB);
- else if (const Function *F = dyn_cast<Function>(V))
+ else if (const Function *F = dyn_cast<Function>(&V))
AW->write(F);
- else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(&V))
AW->write(GV);
else
- AW->writeOperand(V, true, true);
+ AW->writeOperand(&V, true, true);
return *this;
}
-CachedWriter& CachedWriter::operator<<(const Type *Ty) {
+CachedWriter& CachedWriter::operator<<(const Type &Ty) {
if (SymbolicTypes) {
const Module *M = AW->getModule();
- if (M) WriteTypeSymbolic(Out, Ty, M);
+ if (M) WriteTypeSymbolic(Out, &Ty, M);
} else {
- AW->write(Ty);
+ AW->write(&Ty);
}
return *this;
}
SlotMachine::SlotMachine(const Module *M)
: TheModule(M) ///< Saved for lazy initialization.
, TheFunction(0)
+ , FunctionProcessed(false)
, mMap()
, mTypes()
, fMap()
SlotMachine::SlotMachine(const Function *F )
: TheModule( F ? F->getParent() : 0 ) ///< Saved for lazy initialization
, TheFunction(F) ///< Saved for lazy initialization
+ , FunctionProcessed(false)
, mMap()
, mTypes()
, fMap()
processModule();
TheModule = 0; ///< Prevent re-processing next time we're called.
}
- if ( TheFunction ) {
+ if ( TheFunction && ! FunctionProcessed) {
processFunction();
}
}
}
}
+ FunctionProcessed = true;
+
SC_DEBUG("end processFunction!\n");
}
fMap.clear(); // Simply discard the function level map
fTypes.clear();
TheFunction = 0;
+ FunctionProcessed = false;
SC_DEBUG("end purgeFunction!\n");
}
// Check for uninitialized state and do lazy initialization
this->initialize();
- // Do not number CPR's at all. They are an abomination
- if ( const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(V) )
- V = CPR->getValue() ;
-
// Get the type of the value
const Type* VTy = V->getType();
SC_DEBUG(" Inserting value [" << VTy << "] = " << V << " slot=" <<
DestSlot << " [");
// G = Global, C = Constant, T = Type, F = Function, o = other
- SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : (isa<Constant>(V) ? 'C' :
- (isa<Function>(V) ? 'F' : 'o'))));
+ SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : (isa<Function>(V) ? 'F' :
+ (isa<Constant>(V) ? 'C' : 'o'))));
SC_DEBUG("]\n");
return DestSlot;
}