//===----------------------------------------------------------------------===//
#include "CTargetMachine.h"
-#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/Mangler.h"
-#include "Support/StringExtras.h"
-#include "Config/config.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Config/config.h"
#include <algorithm>
+#include <iostream>
#include <sstream>
using namespace llvm;
namespace {
+ // Register the target.
+ RegisterTarget<CTargetMachine> X("c", " C backend");
+
/// NameAllUsedStructs - This pass inserts names for any unnamed structure
/// types that are used by the program.
///
- class CBackendNameAllUsedStructs : public Pass {
+ class CBackendNameAllUsedStructs : public ModulePass {
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<FindUsedTypes>();
}
return "C backend type canonicalizer";
}
- virtual bool run(Module &M);
+ virtual bool runOnModule(Module &M);
};
/// CWriter - This class is the main chunk of code that converts an LLVM
bool runOnFunction(Function &F) {
LI = &getAnalysis<LoopInfo>();
+ // Get rid of intrinsics we can't handle.
+ lowerIntrinsics(F);
+
// Output all floating point constants that cannot be printed accurately.
printFloatingPointConstants(F);
-
- lowerIntrinsics(F);
+
+ // Ensure that no local symbols conflict with global symbols.
+ F.renameLocalSymbols();
+
printFunction(F);
FPConstantMap.clear();
return false;
void visitUnwindInst(UnwindInst &I) {
assert(0 && "Lowerinvoke pass didn't work!");
}
+ void visitUnreachableInst(UnreachableInst &I);
void visitPHINode(PHINode &I);
void visitBinaryOperator(Instruction &I);
void visitCastInst (CastInst &I);
void visitSelectInst(SelectInst &I);
void visitCallInst (CallInst &I);
- void visitCallSite (CallSite CS);
void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
void visitMallocInst(MallocInst &I);
}
bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To);
- void printPHICopiesForSuccessors(BasicBlock *CurBlock,
- unsigned Indent);
+ void printPHICopiesForSuccessor(BasicBlock *CurBlock,
+ BasicBlock *Successor, unsigned Indent);
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
unsigned Indent);
void printIndexingExpression(Value *Ptr, gep_type_iterator I,
gep_type_iterator E);
+ void printCodeForMain();
};
}
/// the program, and removes names from structure types that are not used by the
/// program.
///
-bool CBackendNameAllUsedStructs::run(Module &M) {
+bool CBackendNameAllUsedStructs::runOnModule(Module &M) {
// Get a set of types that are used by the program...
std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes();
// Loop over the module symbol table, removing types from UT that are
- // already named, and removing names for structure types that are not used.
+ // already named, and removing names for types that are not used.
//
SymbolTable &MST = M.getSymbolTable();
for (SymbolTable::type_iterator TI = MST.type_begin(), TE = MST.type_end();
TI != TE; ) {
SymbolTable::type_iterator I = TI++;
- if (StructType *STy = dyn_cast<StructType>(I->second)) {
- // If this is not used, remove it from the symbol table.
- std::set<const Type *>::iterator UTI = UT.find(STy);
- if (UTI == UT.end())
- MST.remove(I);
- else
- UT.erase(UTI);
- }
+
+ // If this is not used, remove it from the symbol table.
+ std::set<const Type *>::iterator UTI = UT.find(I->second);
+ if (UTI == UT.end())
+ MST.remove(I);
+ else
+ UT.erase(UTI); // Only keep one name for this type.
}
// UT now contains types that are not named. Loop over it, naming
case Type::FloatTyID: return Out << "float " << NameSoFar;
case Type::DoubleTyID: return Out << "double " << NameSoFar;
default :
- std::cerr << "Unknown primitive type: " << Ty << "\n";
+ std::cerr << "Unknown primitive type: " << *Ty << "\n";
abort();
}
// Check to see if the type is named.
if (!IgnoreName || isa<OpaqueType>(Ty)) {
std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
- if (I != TypeNames.end()) return Out << I->second << " " << NameSoFar;
+ if (I != TypeNames.end()) return Out << I->second << ' ' << NameSoFar;
}
switch (Ty->getTypeID()) {
} else if (!MTy->getNumParams()) {
FunctionInnards << "void";
}
- FunctionInnards << ")";
+ FunctionInnards << ')';
std::string tstr = FunctionInnards.str();
printType(Out, MTy->getReturnType(), tstr);
return Out;
printType(Out, *I, "field" + utostr(Idx++));
Out << ";\n";
}
- return Out << "}";
+ return Out << '}';
}
case Type::PointerTyID: {
case Type::ArrayTyID: {
const ArrayType *ATy = cast<ArrayType>(Ty);
unsigned NumElements = ATy->getNumElements();
+ if (NumElements == 0) NumElements = 1;
return printType(Out, ATy->getElementType(),
NameSoFar + "[" + utostr(NumElements) + "]");
}
std::string TyName = "struct opaque_" + itostr(Count++);
assert(TypeNames.find(Ty) == TypeNames.end());
TypeNames[Ty] = TyName;
- return Out << TyName << " " << NameSoFar;
+ return Out << TyName << ' ' << NameSoFar;
}
default:
assert(0 && "Unhandled case in getTypeProps!");
isString = false;
if (isString) {
- Out << "\"";
+ Out << '\"';
// Keep track of whether the last number was a hexadecimal escape
bool LastWasHex = false;
}
}
}
- Out << "\"";
+ Out << '\"';
} else {
- Out << "{";
+ Out << '{';
if (CPA->getNumOperands()) {
- Out << " ";
+ Out << ' ';
printConstant(cast<Constant>(CPA->getOperand(0)));
for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
Out << ", ";
case Instruction::Cast:
Out << "((";
printType(Out, CPV->getType());
- Out << ")";
+ Out << ')';
printConstant(CE->getOperand(0));
- Out << ")";
+ Out << ')';
return;
case Instruction::GetElementPtr:
Out << "))";
return;
case Instruction::Select:
- Out << "(";
+ Out << '(';
printConstant(CE->getOperand(0));
- Out << "?";
+ Out << '?';
printConstant(CE->getOperand(1));
- Out << ":";
+ Out << ':';
printConstant(CE->getOperand(2));
- Out << ")";
+ Out << ')';
return;
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
case Instruction::Div:
case Instruction::Rem:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
case Instruction::SetEQ:
case Instruction::SetNE:
case Instruction::SetLT:
case Instruction::SetGE:
case Instruction::Shl:
case Instruction::Shr:
- Out << "(";
+ Out << '(';
printConstant(CE->getOperand(0));
switch (CE->getOpcode()) {
case Instruction::Add: Out << " + "; break;
case Instruction::Mul: Out << " * "; break;
case Instruction::Div: Out << " / "; break;
case Instruction::Rem: Out << " % "; break;
+ case Instruction::And: Out << " & "; break;
+ case Instruction::Or: Out << " | "; break;
+ case Instruction::Xor: Out << " ^ "; break;
case Instruction::SetEQ: Out << " == "; break;
case Instruction::SetNE: Out << " != "; break;
case Instruction::SetLT: Out << " < "; break;
default: assert(0 && "Illegal opcode here!");
}
printConstant(CE->getOperand(1));
- Out << ")";
+ Out << ')';
return;
default:
std::cerr << "CWriter Error: Unhandled constant expression: "
- << CE << "\n";
+ << *CE << "\n";
abort();
}
+ } else if (isa<UndefValue>(CPV) && CPV->getType()->isFirstClassType()) {
+ Out << "((";
+ printType(Out, CPV->getType());
+ Out << ")/*UNDEF*/0)";
+ return;
}
switch (CPV->getType()->getTypeID()) {
case Type::BoolTyID:
- Out << (CPV == ConstantBool::False ? "0" : "1"); break;
+ Out << (CPV == ConstantBool::False ? '0' : '1'); break;
case Type::SByteTyID:
case Type::ShortTyID:
Out << cast<ConstantSInt>(CPV)->getValue(); break;
case Type::IntTyID:
if ((int)cast<ConstantSInt>(CPV)->getValue() == (int)0x80000000)
- Out << "((int)0x80000000)"; // Handle MININT specially to avoid warning
+ Out << "((int)0x80000000U)"; // Handle MININT specially to avoid warning
else
Out << cast<ConstantSInt>(CPV)->getValue();
break;
case Type::LongTyID:
- Out << cast<ConstantSInt>(CPV)->getValue() << "ll"; break;
+ if (cast<ConstantSInt>(CPV)->isMinValue())
+ Out << "(/*INT64_MIN*/(-9223372036854775807LL)-1)";
+ else
+ Out << cast<ConstantSInt>(CPV)->getValue() << "ll"; break;
case Type::UByteTyID:
case Type::UShortTyID:
Out << cast<ConstantUInt>(CPV)->getValue(); break;
case Type::UIntTyID:
- Out << cast<ConstantUInt>(CPV)->getValue() << "u"; break;
+ Out << cast<ConstantUInt>(CPV)->getValue() << 'u'; break;
case Type::ULongTyID:
Out << cast<ConstantUInt>(CPV)->getValue() << "ull"; break;
// Because of FP precision problems we must load from a stack allocated
// value that holds the value in hex.
Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
- << "*)&FPConstant" << I->second << ")";
+ << "*)&FPConstant" << I->second << ')';
} else {
+ if (IsNAN(FPC->getValue())) {
+ // The value is NaN
+
+ // The prefix for a quiet NaN is 0x7FF8. For a signalling NaN,
+ // it's 0x7ff4.
+ const unsigned long QuietNaN = 0x7ff8UL;
+ const unsigned long SignalNaN = 0x7ff4UL;
+
+ // We need to grab the first part of the FP #
+ union {
+ double d;
+ uint64_t ll;
+ } DHex;
+ char Buffer[100];
+
+ DHex.d = FPC->getValue();
+ sprintf(Buffer, "0x%llx", (unsigned long long)DHex.ll);
+
+ std::string Num(&Buffer[0], &Buffer[6]);
+ unsigned long Val = strtoul(Num.c_str(), 0, 16);
+
+ if (FPC->getType() == Type::FloatTy)
+ Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "F(\""
+ << Buffer << "\") /*nan*/ ";
+ else
+ Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "(\""
+ << Buffer << "\") /*nan*/ ";
+ } else if (IsInf(FPC->getValue())) {
+ // The value is Inf
+ if (FPC->getValue() < 0) Out << '-';
+ Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "")
+ << " /*inf*/ ";
+ } else {
+ std::string Num;
#if HAVE_PRINTF_A
- // Print out the constant as a floating point number.
- char Buffer[100];
- sprintf(Buffer, "%a", FPC->getValue());
- Out << Buffer << " /*" << FPC->getValue() << "*/ ";
+ // Print out the constant as a floating point number.
+ char Buffer[100];
+ sprintf(Buffer, "%a", FPC->getValue());
+ Num = Buffer;
#else
- Out << ftostr(FPC->getValue());
+ Num = ftostr(FPC->getValue());
#endif
+ Out << Num;
+ }
}
break;
}
case Type::ArrayTyID:
- if (isa<ConstantAggregateZero>(CPV)) {
+ if (isa<ConstantAggregateZero>(CPV) || isa<UndefValue>(CPV)) {
const ArrayType *AT = cast<ArrayType>(CPV->getType());
- Out << "{";
+ Out << '{';
if (AT->getNumElements()) {
- Out << " ";
+ Out << ' ';
Constant *CZ = Constant::getNullValue(AT->getElementType());
printConstant(CZ);
for (unsigned i = 1, e = AT->getNumElements(); i != e; ++i) {
break;
case Type::StructTyID:
- if (isa<ConstantAggregateZero>(CPV)) {
+ if (isa<ConstantAggregateZero>(CPV) || isa<UndefValue>(CPV)) {
const StructType *ST = cast<StructType>(CPV->getType());
- Out << "{";
+ Out << '{';
if (ST->getNumElements()) {
- Out << " ";
+ Out << ' ';
printConstant(Constant::getNullValue(ST->getElementType(0)));
for (unsigned i = 1, e = ST->getNumElements(); i != e; ++i) {
Out << ", ";
}
Out << " }";
} else {
- Out << "{";
+ Out << '{';
if (CPV->getNumOperands()) {
- Out << " ";
+ Out << ' ';
printConstant(cast<Constant>(CPV->getOperand(0)));
for (unsigned i = 1, e = CPV->getNumOperands(); i != e; ++i) {
Out << ", ";
printType(Out, CPV->getType());
Out << ")/*NULL*/0)";
break;
- } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CPV)) {
- writeOperand(CPR->getValue());
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(CPV)) {
+ writeOperand(GV);
break;
}
// FALL THROUGH
default:
- std::cerr << "Unknown constant type: " << CPV << "\n";
+ std::cerr << "Unknown constant type: " << *CPV << "\n";
abort();
}
}
if (Instruction *I = dyn_cast<Instruction>(Operand))
if (isInlinableInst(*I) && !isDirectAlloca(I)) {
// Should we inline this instruction to build a tree?
- Out << "(";
+ Out << '(';
visit(*I);
- Out << ")";
+ Out << ')';
return;
}
- if (Constant *CPV = dyn_cast<Constant>(Operand)) {
+ Constant* CPV = dyn_cast<Constant>(Operand);
+ if (CPV && !isa<GlobalValue>(CPV)) {
printConstant(CPV);
} else {
Out << Mang->getValueName(Operand);
writeOperandInternal(Operand);
if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand))
- Out << ")";
+ Out << ')';
}
// generateCompilerSpecificCode - This is where we add conditional compilation
static void generateCompilerSpecificCode(std::ostream& Out) {
// Alloca is hard to get, and we don't want to include stdlib.h here...
Out << "/* get a declaration for alloca */\n"
- << "#if defined(sun) || defined(__CYGWIN__)\n"
+ << "#if defined(__CYGWIN__)\n"
+ << "extern void *_alloca(unsigned long);\n"
+ << "#define alloca(x) _alloca(x)\n"
+ << "#elif defined(__APPLE__)\n"
<< "extern void *__builtin_alloca(unsigned long);\n"
<< "#define alloca(x) __builtin_alloca(x)\n"
+ << "#elif defined(__sun__)\n"
+ << "#if defined(__sparcv9)\n"
+ << "extern void *__builtin_alloca(unsigned long);\n"
<< "#else\n"
- << "#ifndef __FreeBSD__\n"
- << "#include <alloca.h>\n"
+ << "extern void *__builtin_alloca(unsigned int);\n"
<< "#endif\n"
+ << "#define alloca(x) __builtin_alloca(x)\n"
+ << "#elif defined(__FreeBSD__)\n"
+ << "#define alloca(x) __builtin_alloca(x)\n"
+ << "#elif !defined(_MSC_VER)\n"
+ << "#include <alloca.h>\n"
<< "#endif\n\n";
// We output GCC specific attributes to preserve 'linkonce'ness on globals.
<< "#else\n"
<< "#define __ATTRIBUTE_WEAK__\n"
<< "#endif\n\n";
+
+ // Define NaN and Inf as GCC builtins if using GCC, as 0 otherwise
+ // From the GCC documentation:
+ //
+ // double __builtin_nan (const char *str)
+ //
+ // This is an implementation of the ISO C99 function nan.
+ //
+ // Since ISO C99 defines this function in terms of strtod, which we do
+ // not implement, a description of the parsing is in order. The string is
+ // parsed as by strtol; that is, the base is recognized by leading 0 or
+ // 0x prefixes. The number parsed is placed in the significand such that
+ // the least significant bit of the number is at the least significant
+ // bit of the significand. The number is truncated to fit the significand
+ // field provided. The significand is forced to be a quiet NaN.
+ //
+ // This function, if given a string literal, is evaluated early enough
+ // that it is considered a compile-time constant.
+ //
+ // float __builtin_nanf (const char *str)
+ //
+ // Similar to __builtin_nan, except the return type is float.
+ //
+ // double __builtin_inf (void)
+ //
+ // Similar to __builtin_huge_val, except a warning is generated if the
+ // target floating-point format does not support infinities. This
+ // function is suitable for implementing the ISO C99 macro INFINITY.
+ //
+ // float __builtin_inff (void)
+ //
+ // Similar to __builtin_inf, except the return type is float.
+ Out << "#ifdef __GNUC__\n"
+ << "#define LLVM_NAN(NanStr) __builtin_nan(NanStr) /* Double */\n"
+ << "#define LLVM_NANF(NanStr) __builtin_nanf(NanStr) /* Float */\n"
+ << "#define LLVM_NANS(NanStr) __builtin_nans(NanStr) /* Double */\n"
+ << "#define LLVM_NANSF(NanStr) __builtin_nansf(NanStr) /* Float */\n"
+ << "#define LLVM_INF __builtin_inf() /* Double */\n"
+ << "#define LLVM_INFF __builtin_inff() /* Float */\n"
+ << "#define LLVM_PREFETCH(addr,rw,locality) __builtin_prefetch(addr,rw,locality)\n"
+ << "#else\n"
+ << "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n"
+ << "#define LLVM_NANF(NanStr) 0.0F /* Float */\n"
+ << "#define LLVM_NANS(NanStr) ((double)0.0) /* Double */\n"
+ << "#define LLVM_NANSF(NanStr) 0.0F /* Float */\n"
+ << "#define LLVM_INF ((double)0.0) /* Double */\n"
+ << "#define LLVM_INFF 0.0F /* Float */\n"
+ << "#define LLVM_PREFETCH(addr,rw,locality) \n"
+ << "#endif\n";
}
bool CWriter::doInitialization(Module &M) {
printModuleTypes(M.getSymbolTable());
// Global variable declarations...
- if (!M.gempty()) {
+ if (!M.global_empty()) {
Out << "\n/* External Global Variable Declarations */\n";
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
if (I->hasExternalLinkage()) {
Out << "extern ";
printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
}
// Output the global variable declarations
- if (!M.gempty()) {
+ if (!M.global_empty()) {
Out << "\n\n/* Global Variable Declarations */\n";
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
if (!I->isExternal()) {
- Out << "extern ";
+ if (I->hasInternalLinkage())
+ Out << "static ";
+ else
+ Out << "extern ";
printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
if (I->hasLinkOnceLinkage())
}
// Output the global variable definitions and contents...
- if (!M.gempty()) {
+ if (!M.global_empty()) {
Out << "\n\n/* Global Variable Definitions and Initialization */\n";
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
if (!I->isExternal()) {
if (I->hasInternalLinkage())
Out << "static ";
assert(0 && "Unknown float type!");
}
- Out << "\n";
+ Out << '\n';
}
/// type name is found, emit it's declaration...
///
void CWriter::printModuleTypes(const SymbolTable &ST) {
- // If there are no type names, exit early.
- if ( ! ST.hasTypes() )
- return;
-
- // We are only interested in the type plane of the symbol table...
+ // We are only interested in the type plane of the symbol table.
SymbolTable::type_const_iterator I = ST.type_begin();
SymbolTable::type_const_iterator End = ST.type_end();
+
+ // If there are no type names, exit early.
+ if (I == End) return;
// Print out forward declarations for structure types before anything else!
Out << "/* Structure forward decls */\n";
TypeNames.insert(std::make_pair(STy, Name));
}
- Out << "\n";
+ Out << '\n';
// Now we can print out typedefs...
Out << "/* Typedefs */\n";
Out << ";\n";
}
- Out << "\n";
+ Out << '\n';
// Keep track of which structures have been printed so far...
std::set<const StructType *> StructPrinted;
std::stringstream FunctionInnards;
// Print out the name...
- FunctionInnards << Mang->getValueName(F) << "(";
+ FunctionInnards << Mang->getValueName(F) << '(';
if (!F->isExternal()) {
- if (!F->aempty()) {
+ if (!F->arg_empty()) {
std::string ArgName;
- if (F->abegin()->hasName() || !Prototype)
- ArgName = Mang->getValueName(F->abegin());
- printType(FunctionInnards, F->afront().getType(), ArgName);
- for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
+ if (F->arg_begin()->hasName() || !Prototype)
+ ArgName = Mang->getValueName(F->arg_begin());
+ printType(FunctionInnards, F->arg_begin()->getType(), ArgName);
+ for (Function::const_arg_iterator I = ++F->arg_begin(), E = F->arg_end();
I != E; ++I) {
FunctionInnards << ", ";
if (I->hasName() || !Prototype)
} else if (!FT->isVarArg() && FT->getNumParams() == 0) {
FunctionInnards << "void"; // ret() -> ret(void) in C.
}
- FunctionInnards << ")";
+ FunctionInnards << ')';
// Print out the return type and the entire signature for that matter
printType(Out, F->getReturnType(), FunctionInnards.str());
}
if (const AllocaInst *AI = isDirectAlloca(&*I)) {
Out << " ";
printType(Out, AI->getAllocatedType(), Mang->getValueName(AI));
- Out << "; /* Address exposed local */\n";
+ Out << "; /* Address-exposed local */\n";
} else if (I->getType() != Type::VoidTy && !isInlinableInst(*I)) {
Out << " ";
printType(Out, I->getType(), Mang->getValueName(&*I));
}
}
- Out << "\n";
+ Out << '\n';
+
+ if (F.hasExternalLinkage() && F.getName() == "main")
+ printCodeForMain();
// print the basic blocks
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
Out << "}\n\n";
}
+void CWriter::printCodeForMain() {
+ // On X86, set the FP control word to 64-bits of precision instead of 80 bits.
+ Out << "#if defined(__GNUC__) && !defined(__llvm__)\n"
+ << "#if defined(i386) || defined(__i386__) || defined(__i386)\n"
+ << "{short FPCW;__asm__ (\"fnstcw %0\" : \"=m\" (*&FPCW));\n"
+ << "FPCW=(FPCW&~0x300)|0x200;__asm__(\"fldcw %0\" :: \"m\" (*&FPCW));}\n"
+ << "#endif\n#endif\n";
+}
+
void CWriter::printLoop(Loop *L) {
Out << " do { /* Syntactic loop '" << L->getHeader()->getName()
<< "' to make GCC happy */\n";
Out << " return";
if (I.getNumOperands()) {
- Out << " ";
+ Out << ' ';
writeOperand(I.getOperand(0));
}
Out << ";\n";
}
void CWriter::visitSwitchInst(SwitchInst &SI) {
- printPHICopiesForSuccessors(SI.getParent(), 0);
Out << " switch (";
writeOperand(SI.getOperand(0));
Out << ") {\n default:\n";
+ printPHICopiesForSuccessor (SI.getParent(), SI.getDefaultDest(), 2);
printBranchToBlock(SI.getParent(), SI.getDefaultDest(), 2);
Out << ";\n";
for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2) {
writeOperand(SI.getOperand(i));
Out << ":\n";
BasicBlock *Succ = cast<BasicBlock>(SI.getOperand(i+1));
+ printPHICopiesForSuccessor (SI.getParent(), Succ, 2);
printBranchToBlock(SI.getParent(), Succ, 2);
- if (Succ == SI.getParent()->getNext())
+ if (Function::iterator(Succ) == next(Function::iterator(SI.getParent())))
Out << " break;\n";
}
Out << " }\n";
}
+void CWriter::visitUnreachableInst(UnreachableInst &I) {
+ Out << " /*UNREACHABLE*/;\n";
+}
+
bool CWriter::isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) {
/// FIXME: This should be reenabled, but loop reordering safe!!
return true;
- if (From->getNext() != To) // Not the direct successor, we need a goto
- return true;
+ if (next(Function::iterator(From)) != Function::iterator(To))
+ return true; // Not the direct successor, we need a goto.
//isa<SwitchInst>(From->getTerminator())
-
if (LI->getLoopFor(From) != LI->getLoopFor(To))
return true;
return false;
}
-void CWriter::printPHICopiesForSuccessors(BasicBlock *CurBlock,
+void CWriter::printPHICopiesForSuccessor (BasicBlock *CurBlock,
+ BasicBlock *Successor,
unsigned Indent) {
- for (succ_iterator SI = succ_begin(CurBlock), E = succ_end(CurBlock);
- SI != E; ++SI)
- for (BasicBlock::iterator I = SI->begin();
- PHINode *PN = dyn_cast<PHINode>(I); ++I) {
- // now we have to do the printing
+ for (BasicBlock::iterator I = Successor->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PN = cast<PHINode>(I);
+ // Now we have to do the printing.
+ Value *IV = PN->getIncomingValueForBlock(CurBlock);
+ if (!isa<UndefValue>(IV)) {
Out << std::string(Indent, ' ');
Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = ";
- writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBlock)));
+ writeOperand(IV);
Out << "; /* for PHI node */\n";
}
+ }
}
-
void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ,
unsigned Indent) {
if (isGotoCodeNecessary(CurBB, Succ)) {
// that immediately succeeds the current one.
//
void CWriter::visitBranchInst(BranchInst &I) {
- printPHICopiesForSuccessors(I.getParent(), 0);
if (I.isConditional()) {
if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(0))) {
writeOperand(I.getCondition());
Out << ") {\n";
+ printPHICopiesForSuccessor (I.getParent(), I.getSuccessor(0), 2);
printBranchToBlock(I.getParent(), I.getSuccessor(0), 2);
if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(1))) {
Out << " } else {\n";
+ printPHICopiesForSuccessor (I.getParent(), I.getSuccessor(1), 2);
printBranchToBlock(I.getParent(), I.getSuccessor(1), 2);
}
} else {
writeOperand(I.getCondition());
Out << ") {\n";
+ printPHICopiesForSuccessor (I.getParent(), I.getSuccessor(1), 2);
printBranchToBlock(I.getParent(), I.getSuccessor(1), 2);
}
Out << " }\n";
} else {
+ printPHICopiesForSuccessor (I.getParent(), I.getSuccessor(0), 0);
printBranchToBlock(I.getParent(), I.getSuccessor(0), 0);
}
Out << "\n";
printType(Out, I.getType());
Out << ")(";
}
-
- writeOperand(I.getOperand(0));
- switch (I.getOpcode()) {
- case Instruction::Add: Out << " + "; break;
- case Instruction::Sub: Out << " - "; break;
- case Instruction::Mul: Out << "*"; break;
- case Instruction::Div: Out << "/"; break;
- case Instruction::Rem: Out << "%"; break;
- case Instruction::And: Out << " & "; break;
- case Instruction::Or: Out << " | "; break;
- case Instruction::Xor: Out << " ^ "; break;
- case Instruction::SetEQ: Out << " == "; break;
- case Instruction::SetNE: Out << " != "; break;
- case Instruction::SetLE: Out << " <= "; break;
- case Instruction::SetGE: Out << " >= "; break;
- case Instruction::SetLT: Out << " < "; break;
- case Instruction::SetGT: Out << " > "; break;
- case Instruction::Shl : Out << " << "; break;
- case Instruction::Shr : Out << " >> "; break;
- default: std::cerr << "Invalid operator type!" << I; abort();
- }
+ // If this is a negation operation, print it out as such. For FP, we don't
+ // want to print "-0.0 - X".
+ if (BinaryOperator::isNeg(&I)) {
+ Out << "-";
+ writeOperand(BinaryOperator::getNegArgument(cast<BinaryOperator>(&I)));
+
+ } else {
+ writeOperand(I.getOperand(0));
- writeOperand(I.getOperand(1));
+ switch (I.getOpcode()) {
+ case Instruction::Add: Out << " + "; break;
+ case Instruction::Sub: Out << " - "; break;
+ case Instruction::Mul: Out << '*'; break;
+ case Instruction::Div: Out << '/'; break;
+ case Instruction::Rem: Out << '%'; break;
+ case Instruction::And: Out << " & "; break;
+ case Instruction::Or: Out << " | "; break;
+ case Instruction::Xor: Out << " ^ "; break;
+ case Instruction::SetEQ: Out << " == "; break;
+ case Instruction::SetNE: Out << " != "; break;
+ case Instruction::SetLE: Out << " <= "; break;
+ case Instruction::SetGE: Out << " >= "; break;
+ case Instruction::SetLT: Out << " < "; break;
+ case Instruction::SetGT: Out << " > "; break;
+ case Instruction::Shl : Out << " << "; break;
+ case Instruction::Shr : Out << " >> "; break;
+ default: std::cerr << "Invalid operator type!" << I; abort();
+ }
+
+ writeOperand(I.getOperand(1));
+ }
if (needsCast) {
Out << "))";
void CWriter::visitCastInst(CastInst &I) {
if (I.getType() == Type::BoolTy) {
- Out << "(";
+ Out << '(';
writeOperand(I.getOperand(0));
Out << " != 0)";
return;
}
- Out << "(";
+ Out << '(';
printType(Out, I.getType());
- Out << ")";
+ Out << ')';
if (isa<PointerType>(I.getType())&&I.getOperand(0)->getType()->isIntegral() ||
isa<PointerType>(I.getOperand(0)->getType())&&I.getType()->isIntegral()) {
// Avoid "cast to pointer from integer of different size" warnings
case Intrinsic::frameaddress:
case Intrinsic::setjmp:
case Intrinsic::longjmp:
+ case Intrinsic::prefetch:
// We directly implement these intrinsics
break;
default:
// All other intrinsic calls we must lower.
- Instruction *Before = CI->getPrev();
+ Instruction *Before = 0;
+ if (CI != &BB->front())
+ Before = prior(BasicBlock::iterator(CI));
+
IL.LowerIntrinsicCall(CI);
if (Before) { // Move iterator to instruction after call
I = Before; ++I;
Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", ";
// Output the last argument to the enclosing function...
- if (I.getParent()->getParent()->aempty()) {
+ if (I.getParent()->getParent()->arg_empty()) {
std::cerr << "The C backend does not currently support zero "
<< "argument varargs functions, such as '"
<< I.getParent()->getParent()->getName() << "'!\n";
abort();
}
- writeOperand(&I.getParent()->getParent()->aback());
- Out << ")";
+ writeOperand(--I.getParent()->getParent()->arg_end());
+ Out << ')';
return;
case Intrinsic::vaend:
- Out << "va_end(*(va_list*)&";
- writeOperand(I.getOperand(1));
- Out << ")";
+ if (!isa<ConstantPointerNull>(I.getOperand(1))) {
+ Out << "va_end(*(va_list*)&";
+ writeOperand(I.getOperand(1));
+ Out << ')';
+ } else {
+ Out << "va_end(*(va_list*)0)";
+ }
return;
case Intrinsic::vacopy:
Out << "0;";
Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", ";
Out << "*(va_list*)&";
writeOperand(I.getOperand(1));
- Out << ")";
+ Out << ')';
return;
case Intrinsic::returnaddress:
Out << "__builtin_return_address(";
writeOperand(I.getOperand(1));
- Out << ")";
+ Out << ')';
return;
case Intrinsic::frameaddress:
Out << "__builtin_frame_address(";
writeOperand(I.getOperand(1));
- Out << ")";
+ Out << ')';
return;
case Intrinsic::setjmp:
Out << "setjmp(*(jmp_buf*)";
writeOperand(I.getOperand(1));
- Out << ")";
+ Out << ')';
return;
case Intrinsic::longjmp:
Out << "longjmp(*(jmp_buf*)";
writeOperand(I.getOperand(1));
Out << ", ";
writeOperand(I.getOperand(2));
+ Out << ')';
+ return;
+ case Intrinsic::prefetch:
+ Out << "LLVM_PREFETCH((const void *)";
+ writeOperand(I.getOperand(1));
+ Out << ", ";
+ writeOperand(I.getOperand(2));
+ Out << ", ";
+ writeOperand(I.getOperand(3));
Out << ")";
return;
}
}
- visitCallSite(&I);
-}
-void CWriter::visitCallSite(CallSite CS) {
- const PointerType *PTy = cast<PointerType>(CS.getCalledValue()->getType());
+ Value *Callee = I.getCalledValue();
+
+ // GCC is really a PITA. It does not permit codegening casts of functions to
+ // function pointers if they are in a call (it generates a trap instruction
+ // instead!). We work around this by inserting a cast to void* in between the
+ // function and the function pointer cast. Unfortunately, we can't just form
+ // the constant expression here, because the folder will immediately nuke it.
+ //
+ // Note finally, that this is completely unsafe. ANSI C does not guarantee
+ // that void* and function pointers have the same size. :( To deal with this
+ // in the common case, we handle casts where the number of arguments passed
+ // match exactly.
+ //
+ bool WroteCallee = false;
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Callee))
+ if (CE->getOpcode() == Instruction::Cast)
+ if (Function *RF = dyn_cast<Function>(CE->getOperand(0))) {
+ const FunctionType *RFTy = RF->getFunctionType();
+ if (RFTy->getNumParams() == I.getNumOperands()-1) {
+ // If the call site expects a value, and the actual callee doesn't
+ // provide one, return 0.
+ if (I.getType() != Type::VoidTy &&
+ RFTy->getReturnType() == Type::VoidTy)
+ Out << "0 /*actual callee doesn't return value*/; ";
+ Callee = RF;
+ } else {
+ // Ok, just cast the pointer type.
+ Out << "((";
+ printType(Out, CE->getType());
+ Out << ")(void*)";
+ printConstant(RF);
+ Out << ')';
+ WroteCallee = true;
+ }
+ }
+
+ const PointerType *PTy = cast<PointerType>(Callee->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const Type *RetTy = FTy->getReturnType();
- writeOperand(CS.getCalledValue());
- Out << "(";
+ if (!WroteCallee) writeOperand(Callee);
+ Out << '(';
+
+ unsigned NumDeclaredParams = FTy->getNumParams();
+
+ if (I.getNumOperands() != 1) {
+ CallSite::arg_iterator AI = I.op_begin()+1, AE = I.op_end();
+ if (NumDeclaredParams && (*AI)->getType() != FTy->getParamType(0)) {
+ Out << '(';
+ printType(Out, FTy->getParamType(0));
+ Out << ')';
+ }
- if (CS.arg_begin() != CS.arg_end()) {
- CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
writeOperand(*AI);
- for (++AI; AI != AE; ++AI) {
+ unsigned ArgNo;
+ for (ArgNo = 1, ++AI; AI != AE; ++AI, ++ArgNo) {
Out << ", ";
+ if (ArgNo < NumDeclaredParams &&
+ (*AI)->getType() != FTy->getParamType(ArgNo)) {
+ Out << '(';
+ printType(Out, FTy->getParamType(ArgNo));
+ Out << ')';
+ }
writeOperand(*AI);
}
}
- Out << ")";
+ Out << ')';
}
void CWriter::visitMallocInst(MallocInst &I) {
}
void CWriter::visitAllocaInst(AllocaInst &I) {
- Out << "(";
+ Out << '(';
printType(Out, I.getType());
Out << ") alloca(sizeof(";
printType(Out, I.getType()->getElementType());
- Out << ")";
+ Out << ')';
if (I.isArrayAllocation()) {
Out << " * " ;
writeOperand(I.getOperand(0));
}
- Out << ")";
+ Out << ')';
}
void CWriter::visitFreeInst(FreeInst &I) {
// If accessing a global value with no indexing, avoid *(&GV) syndrome
if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) {
HasImplicitAddress = true;
- } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) {
- HasImplicitAddress = true;
- Ptr = CPR->getValue(); // Get to the global...
} else if (isDirectAlloca(Ptr)) {
HasImplicitAddress = true;
}
if (I == E) {
if (!HasImplicitAddress)
- Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
+ Out << '*'; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
writeOperandInternal(Ptr);
return;
writeOperandInternal(Ptr);
if (HasImplicitAddress && (!CI || !CI->isNullValue())) {
- Out << ")";
+ Out << ')';
HasImplicitAddress = false; // HIA is only true if we haven't addressed yet
}
if (isa<StructType>(*I)) {
Out << ".field" << cast<ConstantUInt>(I.getOperand())->getValue();
} else {
- Out << "[";
+ Out << '[';
writeOperand(I.getOperand());
- Out << "]";
+ Out << ']';
}
}
void CWriter::visitLoadInst(LoadInst &I) {
- Out << "*";
+ Out << '*';
+ if (I.isVolatile()) {
+ Out << "((";
+ printType(Out, I.getType());
+ Out << " volatile*)";
+ }
+
writeOperand(I.getOperand(0));
+
+ if (I.isVolatile())
+ Out << ')';
}
void CWriter::visitStoreInst(StoreInst &I) {
- Out << "*";
+ Out << '*';
+ if (I.isVolatile()) {
+ Out << "((";
+ printType(Out, I.getOperand(0)->getType());
+ Out << " volatile*)";
+ }
writeOperand(I.getPointerOperand());
+ if (I.isVolatile()) Out << ')';
Out << " = ";
writeOperand(I.getOperand(0));
}
void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
- Out << "&";
+ Out << '&';
printIndexingExpression(I.getPointerOperand(), gep_type_begin(I),
gep_type_end(I));
}
Out << Mang->getValueName(I.getOperand(0));
Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", ";
printType(Out, I.getArgType());
- Out << ")";
+ Out << ')';
}
void CWriter::visitVAArgInst(VAArgInst &I) {
bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) {
PM.add(createLowerGCPass());
- PM.add(createLowerAllocationsPass());
+ PM.add(createLowerAllocationsPass(true));
PM.add(createLowerInvokePass());
PM.add(new CBackendNameAllUsedStructs());
PM.add(new CWriter(o, getIntrinsicLowering()));
return false;
}
-TargetMachine *llvm::allocateCTargetMachine(const Module &M,
- IntrinsicLowering *IL) {
- return new CTargetMachine(M, IL);
-}
-
// vim: sw=2