diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index dd791872e8e..39cdff49adc 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -229,6 +229,7 @@ namespace { } void writeOperand(const Value *Operand); + void writeOperandInternal(const Value *Operand); string getValueName(const Value *V); @@ -241,6 +242,22 @@ namespace { void printFunction(Function *); + // isInlinableInst - Attempt to inline instructions into their uses to build + // trees as much as possible. To do this, we have to consistently decide + // what is acceptable to inline, so that variable declarations don't get + // printed and an extra copy of the expr is not emitted. + // + static bool isInlinableInst(Instruction *I) { + // Must be an expression, must be used exactly once. If it is dead, we + // emit it inline where it would go. + if (I->getType() == Type::VoidTy || I->use_size() != 1 || + isa(I) || isa(I) || isa(I)) + return false; + + // Only inline instruction it it's use is in the same BB as the inst. + return I->getParent() == cast(I->use_back())->getParent(); + } + // Instruction visitation functions friend class InstVisitor; @@ -306,10 +323,7 @@ string CWriter::getValueName(const Value *V) { return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID()); } -void CWriter::writeOperand(const Value *Operand) { - if (isa(Operand)) - Out << "(&"; // Global variables are references as their addresses by llvm - +void CWriter::writeOperandInternal(const Value *Operand) { if (Operand->hasName()) { Out << getValueName(Operand); } else if (const Constant *CPV = dyn_cast(Operand)) { @@ -324,6 +338,22 @@ void CWriter::writeOperand(const Value *Operand) { assert(Slot >= 0 && "Malformed LLVM!"); Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID(); } +} + +void CWriter::writeOperand(const Value *Operand) { + if (Instruction *I = dyn_cast(Operand)) + if (isInlinableInst(I)) { + // Should we inline this instruction to build a tree? + Out << "("; + visit(I); + Out << ")"; + return; + } + + if (isa(Operand)) + Out << "(&"; // Global variables are references as their addresses by llvm + + writeOperandInternal(Operand); if (isa(Operand)) Out << ")"; @@ -469,7 +499,7 @@ void CWriter::printFunction(Function *F) { // print local variable information for the function for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) - if ((*I)->getType() != Type::VoidTy) { + if ((*I)->getType() != Type::VoidTy && !isInlinableInst(*I)) { Out << " "; printTypeVar((*I)->getType(), getValueName(*I)); Out << ";\n"; @@ -496,8 +526,21 @@ void CWriter::printFunction(Function *F) { if (NeedsLabel) Out << getValueName(BB) << ":\n"; // Output all of the instructions in the basic block... - // print the basic blocks - visit(BB); + for (BasicBlock::iterator II = BB->begin(), E = BB->end()-1; + II != E; ++II) { + if (!isInlinableInst(*II) && !isa(*II)) { + Instruction *I = *II; + if (I->getType() != Type::VoidTy) + outputLValue(I); + else + Out << " "; + visit(I); + Out << ";\n"; + } + } + + // Don't emit prefix or suffix for the terminator... + visit(BB->getTerminator()); } Out << "}\n\n"; @@ -591,15 +634,12 @@ void CWriter::visitBranchInst(BranchInst *I) { void CWriter::visitNot(GenericUnaryInst *I) { - outputLValue(I); Out << "~"; writeOperand(I->getOperand(0)); - Out << ";\n"; } void CWriter::visitBinaryOperator(Instruction *I) { // binary instructions, shift instructions, setCond instructions. - outputLValue(I); if (isa(I->getType())) { Out << "("; printType(I->getType()); @@ -631,24 +671,16 @@ void CWriter::visitBinaryOperator(Instruction *I) { if (isa(I->getType())) Out << "(long long)"; writeOperand(I->getOperand(1)); - Out << ";\n"; } void CWriter::visitCastInst(CastInst *I) { - outputLValue(I); Out << "("; printType(I->getType()); Out << ")"; writeOperand(I->getOperand(0)); - Out << ";\n"; } void CWriter::visitCallInst(CallInst *I) { - if (I->getType() != Type::VoidTy) - outputLValue(I); - else - Out << " "; - const PointerType *PTy = cast(I->getCalledValue()->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); @@ -663,11 +695,10 @@ void CWriter::visitCallInst(CallInst *I) { writeOperand(I->getOperand(op)); } } - Out << ");\n"; + Out << ")"; } void CWriter::visitMallocInst(MallocInst *I) { - outputLValue(I); Out << "("; printType(I->getType()); Out << ")malloc(sizeof("; @@ -678,11 +709,10 @@ void CWriter::visitMallocInst(MallocInst *I) { Out << " * " ; writeOperand(I->getOperand(0)); } - Out << ");\n"; + Out << ")"; } void CWriter::visitAllocaInst(AllocaInst *I) { - outputLValue(I); Out << "("; printType(I->getType()); Out << ") alloca(sizeof("; @@ -692,19 +722,26 @@ void CWriter::visitAllocaInst(AllocaInst *I) { Out << " * " ; writeOperand(I->getOperand(0)); } - Out << ");\n"; + Out << ")"; } void CWriter::visitFreeInst(FreeInst *I) { - Out << " free("; + Out << "free("; writeOperand(I->getOperand(0)); - Out << ");\n"; + Out << ")"; } void CWriter::printIndexingExpr(MemAccessInst *MAI) { MemAccessInst::op_iterator I = MAI->idx_begin(), E = MAI->idx_end(); - if (I == E) + if (I == E) { + // If accessing a global value with no indexing, avoid *(&GV) syndrome + if (GlobalValue *V = dyn_cast(MAI->getPointerOperand())) { + writeOperandInternal(V); + return; + } + Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]' + } writeOperand(MAI->getPointerOperand()); @@ -714,9 +751,8 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) { Constant *CI = dyn_cast(*I); if (CI && CI->isNullValue() && I+1 != E && (*(I+1))->getType() == Type::UByteTy) { - ++I; - Out << "->field" << cast(*I)->getValue(); - ++I; + Out << "->field" << cast(*(I+1))->getValue(); + I += 2; } for (; I != E; ++I) @@ -730,24 +766,18 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) { } void CWriter::visitLoadInst(LoadInst *I) { - outputLValue(I); printIndexingExpr(I); - Out << ";\n"; } void CWriter::visitStoreInst(StoreInst *I) { - Out << " "; printIndexingExpr(I); Out << " = "; writeOperand(I->getOperand(0)); - Out << ";\n"; } void CWriter::visitGetElementPtrInst(GetElementPtrInst *I) { - outputLValue(I); Out << "&"; printIndexingExpr(I); - Out << ";\n"; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index dd791872e8e..39cdff49adc 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -229,6 +229,7 @@ namespace { } void writeOperand(const Value *Operand); + void writeOperandInternal(const Value *Operand); string getValueName(const Value *V); @@ -241,6 +242,22 @@ namespace { void printFunction(Function *); + // isInlinableInst - Attempt to inline instructions into their uses to build + // trees as much as possible. To do this, we have to consistently decide + // what is acceptable to inline, so that variable declarations don't get + // printed and an extra copy of the expr is not emitted. + // + static bool isInlinableInst(Instruction *I) { + // Must be an expression, must be used exactly once. If it is dead, we + // emit it inline where it would go. + if (I->getType() == Type::VoidTy || I->use_size() != 1 || + isa(I) || isa(I) || isa(I)) + return false; + + // Only inline instruction it it's use is in the same BB as the inst. + return I->getParent() == cast(I->use_back())->getParent(); + } + // Instruction visitation functions friend class InstVisitor; @@ -306,10 +323,7 @@ string CWriter::getValueName(const Value *V) { return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID()); } -void CWriter::writeOperand(const Value *Operand) { - if (isa(Operand)) - Out << "(&"; // Global variables are references as their addresses by llvm - +void CWriter::writeOperandInternal(const Value *Operand) { if (Operand->hasName()) { Out << getValueName(Operand); } else if (const Constant *CPV = dyn_cast(Operand)) { @@ -324,6 +338,22 @@ void CWriter::writeOperand(const Value *Operand) { assert(Slot >= 0 && "Malformed LLVM!"); Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID(); } +} + +void CWriter::writeOperand(const Value *Operand) { + if (Instruction *I = dyn_cast(Operand)) + if (isInlinableInst(I)) { + // Should we inline this instruction to build a tree? + Out << "("; + visit(I); + Out << ")"; + return; + } + + if (isa(Operand)) + Out << "(&"; // Global variables are references as their addresses by llvm + + writeOperandInternal(Operand); if (isa(Operand)) Out << ")"; @@ -469,7 +499,7 @@ void CWriter::printFunction(Function *F) { // print local variable information for the function for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) - if ((*I)->getType() != Type::VoidTy) { + if ((*I)->getType() != Type::VoidTy && !isInlinableInst(*I)) { Out << " "; printTypeVar((*I)->getType(), getValueName(*I)); Out << ";\n"; @@ -496,8 +526,21 @@ void CWriter::printFunction(Function *F) { if (NeedsLabel) Out << getValueName(BB) << ":\n"; // Output all of the instructions in the basic block... - // print the basic blocks - visit(BB); + for (BasicBlock::iterator II = BB->begin(), E = BB->end()-1; + II != E; ++II) { + if (!isInlinableInst(*II) && !isa(*II)) { + Instruction *I = *II; + if (I->getType() != Type::VoidTy) + outputLValue(I); + else + Out << " "; + visit(I); + Out << ";\n"; + } + } + + // Don't emit prefix or suffix for the terminator... + visit(BB->getTerminator()); } Out << "}\n\n"; @@ -591,15 +634,12 @@ void CWriter::visitBranchInst(BranchInst *I) { void CWriter::visitNot(GenericUnaryInst *I) { - outputLValue(I); Out << "~"; writeOperand(I->getOperand(0)); - Out << ";\n"; } void CWriter::visitBinaryOperator(Instruction *I) { // binary instructions, shift instructions, setCond instructions. - outputLValue(I); if (isa(I->getType())) { Out << "("; printType(I->getType()); @@ -631,24 +671,16 @@ void CWriter::visitBinaryOperator(Instruction *I) { if (isa(I->getType())) Out << "(long long)"; writeOperand(I->getOperand(1)); - Out << ";\n"; } void CWriter::visitCastInst(CastInst *I) { - outputLValue(I); Out << "("; printType(I->getType()); Out << ")"; writeOperand(I->getOperand(0)); - Out << ";\n"; } void CWriter::visitCallInst(CallInst *I) { - if (I->getType() != Type::VoidTy) - outputLValue(I); - else - Out << " "; - const PointerType *PTy = cast(I->getCalledValue()->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); @@ -663,11 +695,10 @@ void CWriter::visitCallInst(CallInst *I) { writeOperand(I->getOperand(op)); } } - Out << ");\n"; + Out << ")"; } void CWriter::visitMallocInst(MallocInst *I) { - outputLValue(I); Out << "("; printType(I->getType()); Out << ")malloc(sizeof("; @@ -678,11 +709,10 @@ void CWriter::visitMallocInst(MallocInst *I) { Out << " * " ; writeOperand(I->getOperand(0)); } - Out << ");\n"; + Out << ")"; } void CWriter::visitAllocaInst(AllocaInst *I) { - outputLValue(I); Out << "("; printType(I->getType()); Out << ") alloca(sizeof("; @@ -692,19 +722,26 @@ void CWriter::visitAllocaInst(AllocaInst *I) { Out << " * " ; writeOperand(I->getOperand(0)); } - Out << ");\n"; + Out << ")"; } void CWriter::visitFreeInst(FreeInst *I) { - Out << " free("; + Out << "free("; writeOperand(I->getOperand(0)); - Out << ");\n"; + Out << ")"; } void CWriter::printIndexingExpr(MemAccessInst *MAI) { MemAccessInst::op_iterator I = MAI->idx_begin(), E = MAI->idx_end(); - if (I == E) + if (I == E) { + // If accessing a global value with no indexing, avoid *(&GV) syndrome + if (GlobalValue *V = dyn_cast(MAI->getPointerOperand())) { + writeOperandInternal(V); + return; + } + Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]' + } writeOperand(MAI->getPointerOperand()); @@ -714,9 +751,8 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) { Constant *CI = dyn_cast(*I); if (CI && CI->isNullValue() && I+1 != E && (*(I+1))->getType() == Type::UByteTy) { - ++I; - Out << "->field" << cast(*I)->getValue(); - ++I; + Out << "->field" << cast(*(I+1))->getValue(); + I += 2; } for (; I != E; ++I) @@ -730,24 +766,18 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) { } void CWriter::visitLoadInst(LoadInst *I) { - outputLValue(I); printIndexingExpr(I); - Out << ";\n"; } void CWriter::visitStoreInst(StoreInst *I) { - Out << " "; printIndexingExpr(I); Out << " = "; writeOperand(I->getOperand(0)); - Out << ";\n"; } void CWriter::visitGetElementPtrInst(GetElementPtrInst *I) { - outputLValue(I); Out << "&"; printIndexingExpr(I); - Out << ";\n"; } //===----------------------------------------------------------------------===//