* Print structures types correctly

* Clean up generated code to not emit basic block labels and goto
  instructions if they are unneccesary (for example, fall throughs)

llvm-svn: 2578
This commit is contained in:
Chris Lattner 2002-05-09 15:49:41 +00:00
parent 132ba2a411
commit 4933e7e02d
1 changed files with 70 additions and 42 deletions

View File

@ -212,16 +212,15 @@ static string calcTypeNameVar(const Type *Ty,
} }
case Type::StructTyID: { case Type::StructTyID: {
const StructType *STy = cast<const StructType>(Ty); const StructType *STy = cast<const StructType>(Ty);
Result = " struct {\n "; Result = NameSoFar + " {\n";
int indx = 0; unsigned indx = 0;
for (StructType::ElementTypes::const_iterator for (StructType::ElementTypes::const_iterator
I = STy->getElementTypes().begin(), I = STy->getElementTypes().begin(),
E = STy->getElementTypes().end(); I != E; ++I) { E = STy->getElementTypes().end(); I != E; ++I) {
Result += calcTypeNameVar(*I, TypeNames, "field" + itostr(indx++)); Result += " " +calcTypeNameVar(*I, TypeNames, "field" + utostr(indx++));
Result += ";\n "; Result += ";\n";
} }
Result += " }"; Result += "}";
Result += " " + NameSoFar;
break; break;
} }
@ -257,7 +256,7 @@ namespace {
: Out(o), Table(Tab), TheModule(M) { : Out(o), Table(Tab), TheModule(M) {
} }
inline void write(const Module *M) { printModule(M); } inline void write(Module *M) { printModule(M); }
ostream& printTypeVar(const Type *Ty, const string &VariableName) { ostream& printTypeVar(const Type *Ty, const string &VariableName) {
return Out << calcTypeNameVar(Ty, TypeNames, VariableName); return Out << calcTypeNameVar(Ty, TypeNames, VariableName);
@ -272,15 +271,13 @@ namespace {
string getValueName(const Value *V); string getValueName(const Value *V);
private : private :
void printModule(const Module *M); void printModule(Module *M);
void printSymbolTable(const SymbolTable &ST); void printSymbolTable(const SymbolTable &ST);
void printGlobal(const GlobalVariable *GV); void printGlobal(const GlobalVariable *GV);
void printFunctionSignature(const Function *F); void printFunctionSignature(const Function *F);
void printFunctionDecl(const Function *F); // Print just the forward decl void printFunctionDecl(const Function *F); // Print just the forward decl
void printFunction(const Function *); void printFunction(Function *);
void outputBasicBlock(const BasicBlock *);
}; };
/* END class CWriter */ /* END class CWriter */
@ -429,6 +426,17 @@ void CInstPrintVisitor::visitReturnInst(ReturnInst *I) {
Out << ";\n"; Out << ";\n";
} }
// Return true if BB1 immediately preceeds BB2.
static bool BBFollowsBB(BasicBlock *BB1, BasicBlock *BB2) {
Function *F = BB1->getParent();
Function::iterator I = find(F->begin(), F->end(), BB1);
assert(I != F->end() && "BB not in function!");
return *(I+1) == BB2;
}
// Brach instruction printing - Avoid printing out a brach to a basic block that
// immediately succeeds the current one.
//
void CInstPrintVisitor::visitBranchInst(BranchInst *I) { void CInstPrintVisitor::visitBranchInst(BranchInst *I) {
TerminatorInst *tI = cast<TerminatorInst>(I); TerminatorInst *tI = cast<TerminatorInst>(I);
if (I->isConditional()) { if (I->isConditional()) {
@ -436,19 +444,29 @@ void CInstPrintVisitor::visitBranchInst(BranchInst *I) {
CW.writeOperand(I->getCondition()); CW.writeOperand(I->getCondition());
Out << ") {\n"; Out << ") {\n";
printPhiFromNextBlock(tI,0); printPhiFromNextBlock(tI,0);
Out << " goto ";
CW.writeOperand(I->getOperand(0)); if (!BBFollowsBB(I->getParent(), cast<BasicBlock>(I->getOperand(0)))) {
Out << ";\n"; Out << " goto ";
CW.writeOperand(I->getOperand(0));
Out << ";\n";
}
Out << " } else {\n"; Out << " } else {\n";
printPhiFromNextBlock(tI,1); printPhiFromNextBlock(tI,1);
Out << " goto ";
CW.writeOperand(I->getOperand(1)); if (!BBFollowsBB(I->getParent(), cast<BasicBlock>(I->getOperand(1)))) {
Out << ";\n }\n"; Out << " goto ";
CW.writeOperand(I->getOperand(1));
Out << ";\n";
}
Out << " }\n";
} else { } else {
printPhiFromNextBlock(tI,0); printPhiFromNextBlock(tI,0);
Out << " goto ";
CW.writeOperand(I->getOperand(0)); if (!BBFollowsBB(I->getParent(), cast<BasicBlock>(I->getOperand(0)))) {
Out << ";\n"; Out << " goto ";
CW.writeOperand(I->getOperand(0));
Out << ";\n";
}
} }
Out << "\n"; Out << "\n";
} }
@ -607,7 +625,7 @@ string CWriter::getValueName(const Value *V) {
return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID()); return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID());
} }
void CWriter::printModule(const Module *M) { void CWriter::printModule(Module *M) {
// printing stdlib inclusion // printing stdlib inclusion
// Out << "#include <stdlib.h>\n"; // Out << "#include <stdlib.h>\n";
@ -734,24 +752,20 @@ void CWriter::printFunctionSignature(const Function *F) {
} }
void CWriter::printFunction(const Function *F) { void CWriter::printFunction(Function *F) {
if (F->isExternal()) return; if (F->isExternal()) return;
Table.incorporateFunction(F); Table.incorporateFunction(F);
printFunctionSignature(F);
Out << " {\n";
// Process each of the basic blocks, gather information and call the // Process each of the basic blocks, gather information and call the
// output methods on the CLocalVars and Function* objects. // output methods on the CLocalVars and Function* objects.
// gather local variable information for each basic block // gather local variable information for each basic block
InstLocalVarsVisitor ILV(*this); InstLocalVarsVisitor ILV(*this);
ILV.visit((Function *)F); ILV.visit(F);
printFunctionSignature(F);
Out << " {\n";
// Loop over the symbol table, emitting all named constants...
if (F->hasSymbolTable())
printSymbolTable(*F->getSymbolTable());
// print the local variables // print the local variables
// we assume that every local variable is alloca'ed in the C code. // we assume that every local variable is alloca'ed in the C code.
@ -769,21 +783,35 @@ void CWriter::printFunction(const Function *F) {
} }
// print the basic blocks // print the basic blocks
for_each(F->begin(), F->end(), bind_obj(this, &CWriter::outputBasicBlock)); for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
BasicBlock *BB = *I, *Prev = I != F->begin() ? *(I-1) : 0;
Out << "}\n"; // Don't print the label for the basic block if there are no uses, or if the
// only terminator use is the precessor basic block's terminator. We have
// to scan the use list because PHI nodes use basic blocks too but do not
// require a label to be generated.
//
bool NeedsLabel = false;
for (Value::use_iterator UI = BB->use_begin(), UE = BB->use_end();
UI != UE; ++UI)
if (TerminatorInst *TI = dyn_cast<TerminatorInst>(*UI))
if (TI != Prev->getTerminator()) {
NeedsLabel = true;
break;
}
if (NeedsLabel) Out << getValueName(BB) << ":\n";
// Output all of the instructions in the basic block...
// print the basic blocks
CInstPrintVisitor CIPV(*this, Table, Out);
CIPV.visit(BB);
}
Out << "}\n\n";
Table.purgeFunction(); Table.purgeFunction();
} }
void CWriter::outputBasicBlock(const BasicBlock* BB) {
Out << getValueName(BB) << ":\n";
// Output all of the instructions in the basic block...
// print the basic blocks
CInstPrintVisitor CIPV(*this, Table, Out);
CIPV.visit((BasicBlock *) BB);
}
void CWriter::writeOperand(const Value *Operand) { void CWriter::writeOperand(const Value *Operand) {
if (isa<GlobalVariable>(Operand)) if (isa<GlobalVariable>(Operand))
Out << "(&"; // Global variables are references as their addresses by llvm Out << "(&"; // Global variables are references as their addresses by llvm
@ -814,6 +842,6 @@ void WriteToC(const Module *M, ostream &Out) {
assert(M && "You can't write a null module!!"); assert(M && "You can't write a null module!!");
SlotCalculator SlotTable(M, false); SlotCalculator SlotTable(M, false);
CWriter W(Out, SlotTable, M); CWriter W(Out, SlotTable, M);
W.write(M); W.write((Module*)M);
Out.flush(); Out.flush();
} }