mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
Two Cleanups to generated C code:
1. Avoid printing *(&globalvariable), instead print globalvariable alone as a special case. 2. Inline subexpressions into expressions as much as legal that preserves execution characteristics of expressions. Now we get nice (but over-parenthesized, oh well) things like: ltmp_428_7 = spec__putc(((unsigned char )((bsBuff) >> 24)), (bsStream)); instead of five seperate instructions (bsBuff & bsStream are globals). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2587 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4fbf26d2fc
commit
d0c668c380
@ -229,6 +229,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeOperand(const Value *Operand);
|
void writeOperand(const Value *Operand);
|
||||||
|
void writeOperandInternal(const Value *Operand);
|
||||||
|
|
||||||
string getValueName(const Value *V);
|
string getValueName(const Value *V);
|
||||||
|
|
||||||
@ -241,6 +242,22 @@ namespace {
|
|||||||
|
|
||||||
void printFunction(Function *);
|
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<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Only inline instruction it it's use is in the same BB as the inst.
|
||||||
|
return I->getParent() == cast<Instruction>(I->use_back())->getParent();
|
||||||
|
}
|
||||||
|
|
||||||
// Instruction visitation functions
|
// Instruction visitation functions
|
||||||
friend class InstVisitor<CWriter>;
|
friend class InstVisitor<CWriter>;
|
||||||
|
|
||||||
@ -306,10 +323,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::writeOperand(const Value *Operand) {
|
void CWriter::writeOperandInternal(const Value *Operand) {
|
||||||
if (isa<GlobalVariable>(Operand))
|
|
||||||
Out << "(&"; // Global variables are references as their addresses by llvm
|
|
||||||
|
|
||||||
if (Operand->hasName()) {
|
if (Operand->hasName()) {
|
||||||
Out << getValueName(Operand);
|
Out << getValueName(Operand);
|
||||||
} else if (const Constant *CPV = dyn_cast<const Constant>(Operand)) {
|
} else if (const Constant *CPV = dyn_cast<const Constant>(Operand)) {
|
||||||
@ -324,6 +338,22 @@ void CWriter::writeOperand(const Value *Operand) {
|
|||||||
assert(Slot >= 0 && "Malformed LLVM!");
|
assert(Slot >= 0 && "Malformed LLVM!");
|
||||||
Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
|
Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWriter::writeOperand(const Value *Operand) {
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(Operand))
|
||||||
|
if (isInlinableInst(I)) {
|
||||||
|
// Should we inline this instruction to build a tree?
|
||||||
|
Out << "(";
|
||||||
|
visit(I);
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isa<GlobalVariable>(Operand))
|
||||||
|
Out << "(&"; // Global variables are references as their addresses by llvm
|
||||||
|
|
||||||
|
writeOperandInternal(Operand);
|
||||||
|
|
||||||
if (isa<GlobalVariable>(Operand))
|
if (isa<GlobalVariable>(Operand))
|
||||||
Out << ")";
|
Out << ")";
|
||||||
@ -469,7 +499,7 @@ void CWriter::printFunction(Function *F) {
|
|||||||
|
|
||||||
// print local variable information for the function
|
// print local variable information for the function
|
||||||
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
|
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 << " ";
|
Out << " ";
|
||||||
printTypeVar((*I)->getType(), getValueName(*I));
|
printTypeVar((*I)->getType(), getValueName(*I));
|
||||||
Out << ";\n";
|
Out << ";\n";
|
||||||
@ -496,8 +526,21 @@ void CWriter::printFunction(Function *F) {
|
|||||||
if (NeedsLabel) Out << getValueName(BB) << ":\n";
|
if (NeedsLabel) Out << getValueName(BB) << ":\n";
|
||||||
|
|
||||||
// Output all of the instructions in the basic block...
|
// Output all of the instructions in the basic block...
|
||||||
// print the basic blocks
|
for (BasicBlock::iterator II = BB->begin(), E = BB->end()-1;
|
||||||
visit(BB);
|
II != E; ++II) {
|
||||||
|
if (!isInlinableInst(*II) && !isa<PHINode>(*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";
|
Out << "}\n\n";
|
||||||
@ -591,15 +634,12 @@ void CWriter::visitBranchInst(BranchInst *I) {
|
|||||||
|
|
||||||
|
|
||||||
void CWriter::visitNot(GenericUnaryInst *I) {
|
void CWriter::visitNot(GenericUnaryInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "~";
|
Out << "~";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitBinaryOperator(Instruction *I) {
|
void CWriter::visitBinaryOperator(Instruction *I) {
|
||||||
// binary instructions, shift instructions, setCond instructions.
|
// binary instructions, shift instructions, setCond instructions.
|
||||||
outputLValue(I);
|
|
||||||
if (isa<PointerType>(I->getType())) {
|
if (isa<PointerType>(I->getType())) {
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
@ -631,24 +671,16 @@ void CWriter::visitBinaryOperator(Instruction *I) {
|
|||||||
|
|
||||||
if (isa<PointerType>(I->getType())) Out << "(long long)";
|
if (isa<PointerType>(I->getType())) Out << "(long long)";
|
||||||
writeOperand(I->getOperand(1));
|
writeOperand(I->getOperand(1));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitCastInst(CastInst *I) {
|
void CWriter::visitCastInst(CastInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
Out << ")";
|
Out << ")";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitCallInst(CallInst *I) {
|
void CWriter::visitCallInst(CallInst *I) {
|
||||||
if (I->getType() != Type::VoidTy)
|
|
||||||
outputLValue(I);
|
|
||||||
else
|
|
||||||
Out << " ";
|
|
||||||
|
|
||||||
const PointerType *PTy = cast<PointerType>(I->getCalledValue()->getType());
|
const PointerType *PTy = cast<PointerType>(I->getCalledValue()->getType());
|
||||||
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
||||||
const Type *RetTy = FTy->getReturnType();
|
const Type *RetTy = FTy->getReturnType();
|
||||||
@ -663,11 +695,10 @@ void CWriter::visitCallInst(CallInst *I) {
|
|||||||
writeOperand(I->getOperand(op));
|
writeOperand(I->getOperand(op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitMallocInst(MallocInst *I) {
|
void CWriter::visitMallocInst(MallocInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
Out << ")malloc(sizeof(";
|
Out << ")malloc(sizeof(";
|
||||||
@ -678,11 +709,10 @@ void CWriter::visitMallocInst(MallocInst *I) {
|
|||||||
Out << " * " ;
|
Out << " * " ;
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
}
|
}
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitAllocaInst(AllocaInst *I) {
|
void CWriter::visitAllocaInst(AllocaInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
Out << ") alloca(sizeof(";
|
Out << ") alloca(sizeof(";
|
||||||
@ -692,19 +722,26 @@ void CWriter::visitAllocaInst(AllocaInst *I) {
|
|||||||
Out << " * " ;
|
Out << " * " ;
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
}
|
}
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitFreeInst(FreeInst *I) {
|
void CWriter::visitFreeInst(FreeInst *I) {
|
||||||
Out << " free(";
|
Out << "free(";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
||||||
MemAccessInst::op_iterator I = MAI->idx_begin(), E = MAI->idx_end();
|
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<GlobalValue>(MAI->getPointerOperand())) {
|
||||||
|
writeOperandInternal(V);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
||||||
|
}
|
||||||
|
|
||||||
writeOperand(MAI->getPointerOperand());
|
writeOperand(MAI->getPointerOperand());
|
||||||
|
|
||||||
@ -714,9 +751,8 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
|||||||
Constant *CI = dyn_cast<Constant>(*I);
|
Constant *CI = dyn_cast<Constant>(*I);
|
||||||
if (CI && CI->isNullValue() && I+1 != E &&
|
if (CI && CI->isNullValue() && I+1 != E &&
|
||||||
(*(I+1))->getType() == Type::UByteTy) {
|
(*(I+1))->getType() == Type::UByteTy) {
|
||||||
++I;
|
Out << "->field" << cast<ConstantUInt>(*(I+1))->getValue();
|
||||||
Out << "->field" << cast<ConstantUInt>(*I)->getValue();
|
I += 2;
|
||||||
++I;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; I != E; ++I)
|
for (; I != E; ++I)
|
||||||
@ -730,24 +766,18 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitLoadInst(LoadInst *I) {
|
void CWriter::visitLoadInst(LoadInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
printIndexingExpr(I);
|
printIndexingExpr(I);
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitStoreInst(StoreInst *I) {
|
void CWriter::visitStoreInst(StoreInst *I) {
|
||||||
Out << " ";
|
|
||||||
printIndexingExpr(I);
|
printIndexingExpr(I);
|
||||||
Out << " = ";
|
Out << " = ";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitGetElementPtrInst(GetElementPtrInst *I) {
|
void CWriter::visitGetElementPtrInst(GetElementPtrInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "&";
|
Out << "&";
|
||||||
printIndexingExpr(I);
|
printIndexingExpr(I);
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -229,6 +229,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeOperand(const Value *Operand);
|
void writeOperand(const Value *Operand);
|
||||||
|
void writeOperandInternal(const Value *Operand);
|
||||||
|
|
||||||
string getValueName(const Value *V);
|
string getValueName(const Value *V);
|
||||||
|
|
||||||
@ -241,6 +242,22 @@ namespace {
|
|||||||
|
|
||||||
void printFunction(Function *);
|
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<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Only inline instruction it it's use is in the same BB as the inst.
|
||||||
|
return I->getParent() == cast<Instruction>(I->use_back())->getParent();
|
||||||
|
}
|
||||||
|
|
||||||
// Instruction visitation functions
|
// Instruction visitation functions
|
||||||
friend class InstVisitor<CWriter>;
|
friend class InstVisitor<CWriter>;
|
||||||
|
|
||||||
@ -306,10 +323,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::writeOperand(const Value *Operand) {
|
void CWriter::writeOperandInternal(const Value *Operand) {
|
||||||
if (isa<GlobalVariable>(Operand))
|
|
||||||
Out << "(&"; // Global variables are references as their addresses by llvm
|
|
||||||
|
|
||||||
if (Operand->hasName()) {
|
if (Operand->hasName()) {
|
||||||
Out << getValueName(Operand);
|
Out << getValueName(Operand);
|
||||||
} else if (const Constant *CPV = dyn_cast<const Constant>(Operand)) {
|
} else if (const Constant *CPV = dyn_cast<const Constant>(Operand)) {
|
||||||
@ -324,6 +338,22 @@ void CWriter::writeOperand(const Value *Operand) {
|
|||||||
assert(Slot >= 0 && "Malformed LLVM!");
|
assert(Slot >= 0 && "Malformed LLVM!");
|
||||||
Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
|
Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWriter::writeOperand(const Value *Operand) {
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(Operand))
|
||||||
|
if (isInlinableInst(I)) {
|
||||||
|
// Should we inline this instruction to build a tree?
|
||||||
|
Out << "(";
|
||||||
|
visit(I);
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isa<GlobalVariable>(Operand))
|
||||||
|
Out << "(&"; // Global variables are references as their addresses by llvm
|
||||||
|
|
||||||
|
writeOperandInternal(Operand);
|
||||||
|
|
||||||
if (isa<GlobalVariable>(Operand))
|
if (isa<GlobalVariable>(Operand))
|
||||||
Out << ")";
|
Out << ")";
|
||||||
@ -469,7 +499,7 @@ void CWriter::printFunction(Function *F) {
|
|||||||
|
|
||||||
// print local variable information for the function
|
// print local variable information for the function
|
||||||
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
|
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 << " ";
|
Out << " ";
|
||||||
printTypeVar((*I)->getType(), getValueName(*I));
|
printTypeVar((*I)->getType(), getValueName(*I));
|
||||||
Out << ";\n";
|
Out << ";\n";
|
||||||
@ -496,8 +526,21 @@ void CWriter::printFunction(Function *F) {
|
|||||||
if (NeedsLabel) Out << getValueName(BB) << ":\n";
|
if (NeedsLabel) Out << getValueName(BB) << ":\n";
|
||||||
|
|
||||||
// Output all of the instructions in the basic block...
|
// Output all of the instructions in the basic block...
|
||||||
// print the basic blocks
|
for (BasicBlock::iterator II = BB->begin(), E = BB->end()-1;
|
||||||
visit(BB);
|
II != E; ++II) {
|
||||||
|
if (!isInlinableInst(*II) && !isa<PHINode>(*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";
|
Out << "}\n\n";
|
||||||
@ -591,15 +634,12 @@ void CWriter::visitBranchInst(BranchInst *I) {
|
|||||||
|
|
||||||
|
|
||||||
void CWriter::visitNot(GenericUnaryInst *I) {
|
void CWriter::visitNot(GenericUnaryInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "~";
|
Out << "~";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitBinaryOperator(Instruction *I) {
|
void CWriter::visitBinaryOperator(Instruction *I) {
|
||||||
// binary instructions, shift instructions, setCond instructions.
|
// binary instructions, shift instructions, setCond instructions.
|
||||||
outputLValue(I);
|
|
||||||
if (isa<PointerType>(I->getType())) {
|
if (isa<PointerType>(I->getType())) {
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
@ -631,24 +671,16 @@ void CWriter::visitBinaryOperator(Instruction *I) {
|
|||||||
|
|
||||||
if (isa<PointerType>(I->getType())) Out << "(long long)";
|
if (isa<PointerType>(I->getType())) Out << "(long long)";
|
||||||
writeOperand(I->getOperand(1));
|
writeOperand(I->getOperand(1));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitCastInst(CastInst *I) {
|
void CWriter::visitCastInst(CastInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
Out << ")";
|
Out << ")";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitCallInst(CallInst *I) {
|
void CWriter::visitCallInst(CallInst *I) {
|
||||||
if (I->getType() != Type::VoidTy)
|
|
||||||
outputLValue(I);
|
|
||||||
else
|
|
||||||
Out << " ";
|
|
||||||
|
|
||||||
const PointerType *PTy = cast<PointerType>(I->getCalledValue()->getType());
|
const PointerType *PTy = cast<PointerType>(I->getCalledValue()->getType());
|
||||||
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
||||||
const Type *RetTy = FTy->getReturnType();
|
const Type *RetTy = FTy->getReturnType();
|
||||||
@ -663,11 +695,10 @@ void CWriter::visitCallInst(CallInst *I) {
|
|||||||
writeOperand(I->getOperand(op));
|
writeOperand(I->getOperand(op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitMallocInst(MallocInst *I) {
|
void CWriter::visitMallocInst(MallocInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
Out << ")malloc(sizeof(";
|
Out << ")malloc(sizeof(";
|
||||||
@ -678,11 +709,10 @@ void CWriter::visitMallocInst(MallocInst *I) {
|
|||||||
Out << " * " ;
|
Out << " * " ;
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
}
|
}
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitAllocaInst(AllocaInst *I) {
|
void CWriter::visitAllocaInst(AllocaInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "(";
|
Out << "(";
|
||||||
printType(I->getType());
|
printType(I->getType());
|
||||||
Out << ") alloca(sizeof(";
|
Out << ") alloca(sizeof(";
|
||||||
@ -692,19 +722,26 @@ void CWriter::visitAllocaInst(AllocaInst *I) {
|
|||||||
Out << " * " ;
|
Out << " * " ;
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
}
|
}
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitFreeInst(FreeInst *I) {
|
void CWriter::visitFreeInst(FreeInst *I) {
|
||||||
Out << " free(";
|
Out << "free(";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ");\n";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
||||||
MemAccessInst::op_iterator I = MAI->idx_begin(), E = MAI->idx_end();
|
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<GlobalValue>(MAI->getPointerOperand())) {
|
||||||
|
writeOperandInternal(V);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
||||||
|
}
|
||||||
|
|
||||||
writeOperand(MAI->getPointerOperand());
|
writeOperand(MAI->getPointerOperand());
|
||||||
|
|
||||||
@ -714,9 +751,8 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
|||||||
Constant *CI = dyn_cast<Constant>(*I);
|
Constant *CI = dyn_cast<Constant>(*I);
|
||||||
if (CI && CI->isNullValue() && I+1 != E &&
|
if (CI && CI->isNullValue() && I+1 != E &&
|
||||||
(*(I+1))->getType() == Type::UByteTy) {
|
(*(I+1))->getType() == Type::UByteTy) {
|
||||||
++I;
|
Out << "->field" << cast<ConstantUInt>(*(I+1))->getValue();
|
||||||
Out << "->field" << cast<ConstantUInt>(*I)->getValue();
|
I += 2;
|
||||||
++I;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; I != E; ++I)
|
for (; I != E; ++I)
|
||||||
@ -730,24 +766,18 @@ void CWriter::printIndexingExpr(MemAccessInst *MAI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitLoadInst(LoadInst *I) {
|
void CWriter::visitLoadInst(LoadInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
printIndexingExpr(I);
|
printIndexingExpr(I);
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitStoreInst(StoreInst *I) {
|
void CWriter::visitStoreInst(StoreInst *I) {
|
||||||
Out << " ";
|
|
||||||
printIndexingExpr(I);
|
printIndexingExpr(I);
|
||||||
Out << " = ";
|
Out << " = ";
|
||||||
writeOperand(I->getOperand(0));
|
writeOperand(I->getOperand(0));
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitGetElementPtrInst(GetElementPtrInst *I) {
|
void CWriter::visitGetElementPtrInst(GetElementPtrInst *I) {
|
||||||
outputLValue(I);
|
|
||||||
Out << "&";
|
Out << "&";
|
||||||
printIndexingExpr(I);
|
printIndexingExpr(I);
|
||||||
Out << ";\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user