X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FCBackend%2FCBackend.cpp;h=cca896b59d3cf4f7b16c35119b0d0bc5c2c002ac;hb=64cc97212346992892b6c92158c08cd93149a882;hp=4473af1ee6c1082e833e07b18cb7242be4fe02d0;hpb=687a4cb2955ce1b4eaf28134c4f8c57e0cacfa68;p=oota-llvm.git diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 4473af1ee6c..cca896b59d3 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -30,11 +30,14 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/Mangler.h" @@ -48,7 +51,11 @@ using namespace llvm; // Register the target. -static RegisterTarget X("c", " C backend"); +extern Target TheCBackendTarget; +static RegisterTarget X(TheCBackendTarget, "c", "C backend"); + +// Force static initialization. +extern "C" void LLVMInitializeCBackendTarget() { } namespace { /// CBackendNameAllUsedStructsAndMergeFunctions - This pass inserts names for @@ -59,7 +66,7 @@ namespace { public: static char ID; CBackendNameAllUsedStructsAndMergeFunctions() - : ModulePass((intptr_t)&ID) {} + : ModulePass(&ID) {} void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); } @@ -76,7 +83,7 @@ namespace { /// CWriter - This class is the main chunk of code that converts an LLVM /// module to a C translation unit. class CWriter : public FunctionPass, public InstVisitor { - std::ostream &Out; + formatted_raw_ostream &Out; IntrinsicLowering *IL; Mangler *Mang; LoopInfo *LI; @@ -87,12 +94,18 @@ namespace { std::map FPConstantMap; std::set intrinsicPrototypesAlreadyGenerated; std::set ByValParams; + unsigned FPCounter; + unsigned OpaqueCounter; + DenseMap AnonValueNumbers; + unsigned NextAnonValueNumber; public: static char ID; - explicit CWriter(std::ostream &o) - : FunctionPass((intptr_t)&ID), Out(o), IL(0), Mang(0), LI(0), - TheModule(0), TAsm(0), TD(0) {} + explicit CWriter(formatted_raw_ostream &o) + : FunctionPass(&ID), Out(o), IL(0), Mang(0), LI(0), + TheModule(0), TAsm(0), TD(0), OpaqueCounter(0), NextAnonValueNumber(0) { + FPCounter = 0; + } virtual const char *getPassName() const { return "C backend"; } @@ -104,6 +117,11 @@ namespace { virtual bool doInitialization(Module &M); bool runOnFunction(Function &F) { + // Do not codegen any 'available_externally' functions at all, they have + // definitions outside the translation unit. + if (F.hasAvailableExternallyLinkage()) + return false; + LI = &getAnalysis(); // Get rid of intrinsics we can't handle. @@ -118,6 +136,8 @@ namespace { virtual bool doFinalization(Module &M) { // Free memory... + delete IL; + delete TD; delete Mang; FPConstantMap.clear(); TypeNames.clear(); @@ -126,17 +146,27 @@ namespace { return false; } + raw_ostream &printType(formatted_raw_ostream &Out, + const Type *Ty, + bool isSigned = false, + const std::string &VariableName = "", + bool IgnoreName = false, + const AttrListPtr &PAL = AttrListPtr()); std::ostream &printType(std::ostream &Out, const Type *Ty, - bool isSigned = false, - const std::string &VariableName = "", - bool IgnoreName = false, - const PAListPtr &PAL = PAListPtr()); + bool isSigned = false, + const std::string &VariableName = "", + bool IgnoreName = false, + const AttrListPtr &PAL = AttrListPtr()); + raw_ostream &printSimpleType(formatted_raw_ostream &Out, + const Type *Ty, + bool isSigned, + const std::string &NameSoFar = ""); std::ostream &printSimpleType(std::ostream &Out, const Type *Ty, - bool isSigned, - const std::string &NameSoFar = ""); + bool isSigned, + const std::string &NameSoFar = ""); - void printStructReturnPointerFunctionType(std::ostream &Out, - const PAListPtr &PAL, + void printStructReturnPointerFunctionType(formatted_raw_ostream &Out, + const AttrListPtr &PAL, const PointerType *Ty); /// writeOperandDeref - Print the result of dereferencing the specified @@ -153,9 +183,9 @@ namespace { } } - void writeOperand(Value *Operand); - void writeOperandRaw(Value *Operand); - void writeOperandInternal(Value *Operand); + void writeOperand(Value *Operand, bool Static = false); + void writeInstComputationInline(Instruction &I); + void writeOperandInternal(Value *Operand, bool Static = false); void writeOperandWithCast(Value* Operand, unsigned Opcode); void writeOperandWithCast(Value* Operand, const ICmpInst &I); bool writeInstructionCast(const Instruction &I); @@ -170,8 +200,9 @@ namespace { void printModule(Module *M); void printModuleTypes(const TypeSymbolTable &ST); - void printContainedStructs(const Type *Ty, std::set &); + void printContainedStructs(const Type *Ty, std::set &); void printFloatingPointConstants(Function &F); + void printFloatingPointConstants(const Constant *C); void printFunctionSignature(const Function *F, bool Prototype); void printFunction(Function &); @@ -179,11 +210,11 @@ namespace { void printLoop(Loop *L); void printCast(unsigned opcode, const Type *SrcTy, const Type *DstTy); - void printConstant(Constant *CPV); + void printConstant(Constant *CPV, bool Static); void printConstantWithCast(Constant *CPV, unsigned Opcode); - bool printConstExprCast(const ConstantExpr *CE); - void printConstantArray(ConstantArray *CPA); - void printConstantVector(ConstantVector *CV); + bool printConstExprCast(const ConstantExpr *CE, bool Static); + void printConstantArray(ConstantArray *CPA, bool Static); + void printConstantVector(ConstantVector *CV, bool Static); /// isAddressExposed - Return true if the specified value's name needs to /// have its address taken in order to get a C value of the correct type. @@ -209,7 +240,8 @@ namespace { // emit it inline where it would go. if (I.getType() == Type::VoidTy || !I.hasOneUse() || isa(I) || isa(I) || isa(I) || - isa(I) || isa(I) || isa(I)) + isa(I) || isa(I) || isa(I) || + isa(I)) // Don't inline a load across a store or other bad things! return false; @@ -253,11 +285,11 @@ namespace { void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); void visitInvokeInst(InvokeInst &I) { - assert(0 && "Lowerinvoke pass didn't work!"); + llvm_unreachable("Lowerinvoke pass didn't work!"); } void visitUnwindInst(UnwindInst &I) { - assert(0 && "Lowerinvoke pass didn't work!"); + llvm_unreachable("Lowerinvoke pass didn't work!"); } void visitUnreachableInst(UnreachableInst &I); @@ -283,11 +315,15 @@ namespace { void visitInsertElementInst(InsertElementInst &I); void visitExtractElementInst(ExtractElementInst &I); void visitShuffleVectorInst(ShuffleVectorInst &SVI); - void visitGetResultInst(GetResultInst &GRI); + + void visitInsertValueInst(InsertValueInst &I); + void visitExtractValueInst(ExtractValueInst &I); void visitInstruction(Instruction &I) { +#ifndef NDEBUG cerr << "C Writer does not know about " << I; - abort(); +#endif + llvm_unreachable(0); } void outputLValue(Instruction *I) { @@ -300,7 +336,7 @@ namespace { void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock, unsigned Indent); void printGEPExpression(Value *Ptr, gep_type_iterator I, - gep_type_iterator E); + gep_type_iterator E, bool Static); std::string GetValueName(const Value *Operand); }; @@ -324,9 +360,10 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) { TI != TE; ) { TypeSymbolTable::iterator I = TI++; - // If this isn't a struct type, remove it from our set of types to name. - // This simplifies emission later. - if (!isa(I->second) && !isa(I->second)) { + // If this isn't a struct or array type, remove it from our set of types + // to name. This simplifies emission later. + if (!isa(I->second) && !isa(I->second) && + !isa(I->second)) { TST.remove(I); } else { // If this is not used, remove it from the symbol table. @@ -345,8 +382,8 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) { unsigned RenameCounter = 0; for (std::set::const_iterator I = UT.begin(), E = UT.end(); I != E; ++I) - if (const StructType *ST = dyn_cast(*I)) { - while (M.addTypeName("unnamed"+utostr(RenameCounter), ST)) + if (isa(*I) || isa(*I)) { + while (M.addTypeName("unnamed"+utostr(RenameCounter), *I)) ++RenameCounter; Changed = true; } @@ -394,8 +431,8 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) { /// printStructReturnPointerFunctionType - This is like printType for a struct /// return type, except, instead of printing the type as void (*)(Struct*, ...) /// print it as "Struct (*)(...)", for struct return functions. -void CWriter::printStructReturnPointerFunctionType(std::ostream &Out, - const PAListPtr &PAL, +void CWriter::printStructReturnPointerFunctionType(formatted_raw_ostream &Out, + const AttrListPtr &PAL, const PointerType *TheTy) { const FunctionType *FTy = cast(TheTy->getElementType()); std::stringstream FunctionInnards; @@ -409,12 +446,12 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out, if (PrintedType) FunctionInnards << ", "; const Type *ArgTy = *I; - if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) { + if (PAL.paramHasAttr(Idx, Attribute::ByVal)) { assert(isa(ArgTy)); ArgTy = cast(ArgTy)->getElementType(); } printType(FunctionInnards, ArgTy, - /*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt), ""); + /*isSigned=*/PAL.paramHasAttr(Idx, Attribute::SExt), ""); PrintedType = true; } if (FTy->isVarArg()) { @@ -426,7 +463,55 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out, FunctionInnards << ')'; std::string tstr = FunctionInnards.str(); printType(Out, RetTy, - /*isSigned=*/PAL.paramHasAttr(0, ParamAttr::SExt), tstr); + /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), tstr); +} + +raw_ostream & +CWriter::printSimpleType(formatted_raw_ostream &Out, const Type *Ty, + bool isSigned, + const std::string &NameSoFar) { + assert((Ty->isPrimitiveType() || Ty->isInteger() || isa(Ty)) && + "Invalid type for printSimpleType"); + switch (Ty->getTypeID()) { + case Type::VoidTyID: return Out << "void " << NameSoFar; + case Type::IntegerTyID: { + unsigned NumBits = cast(Ty)->getBitWidth(); + if (NumBits == 1) + return Out << "bool " << NameSoFar; + else if (NumBits <= 8) + return Out << (isSigned?"signed":"unsigned") << " char " << NameSoFar; + else if (NumBits <= 16) + return Out << (isSigned?"signed":"unsigned") << " short " << NameSoFar; + else if (NumBits <= 32) + return Out << (isSigned?"signed":"unsigned") << " int " << NameSoFar; + else if (NumBits <= 64) + return Out << (isSigned?"signed":"unsigned") << " long long "<< NameSoFar; + else { + assert(NumBits <= 128 && "Bit widths > 128 not implemented yet"); + return Out << (isSigned?"llvmInt128":"llvmUInt128") << " " << NameSoFar; + } + } + case Type::FloatTyID: return Out << "float " << NameSoFar; + case Type::DoubleTyID: return Out << "double " << NameSoFar; + // Lacking emulation of FP80 on PPC, etc., we assume whichever of these is + // present matches host 'long double'. + case Type::X86_FP80TyID: + case Type::PPC_FP128TyID: + case Type::FP128TyID: return Out << "long double " << NameSoFar; + + case Type::VectorTyID: { + const VectorType *VTy = cast(Ty); + return printSimpleType(Out, VTy->getElementType(), isSigned, + " __attribute__((vector_size(" + + utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar); + } + + default: +#ifndef NDEBUG + cerr << "Unknown primitive type: " << *Ty << "\n"; +#endif + llvm_unreachable(0); + } } std::ostream & @@ -465,13 +550,119 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned, const VectorType *VTy = cast(Ty); return printSimpleType(Out, VTy->getElementType(), isSigned, " __attribute__((vector_size(" + - utostr(TD->getABITypeSize(VTy)) + " ))) " + NameSoFar); + utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar); } default: +#ifndef NDEBUG cerr << "Unknown primitive type: " << *Ty << "\n"; - abort(); +#endif + llvm_unreachable(0); + } +} + +// Pass the Type* and the variable name and this prints out the variable +// declaration. +// +raw_ostream &CWriter::printType(formatted_raw_ostream &Out, + const Type *Ty, + bool isSigned, const std::string &NameSoFar, + bool IgnoreName, const AttrListPtr &PAL) { + if (Ty->isPrimitiveType() || Ty->isInteger() || isa(Ty)) { + printSimpleType(Out, Ty, isSigned, NameSoFar); + return Out; + } + + // Check to see if the type is named. + if (!IgnoreName || isa(Ty)) { + std::map::iterator I = TypeNames.find(Ty); + if (I != TypeNames.end()) return Out << I->second << ' ' << NameSoFar; + } + + switch (Ty->getTypeID()) { + case Type::FunctionTyID: { + const FunctionType *FTy = cast(Ty); + std::stringstream FunctionInnards; + FunctionInnards << " (" << NameSoFar << ") ("; + unsigned Idx = 1; + for (FunctionType::param_iterator I = FTy->param_begin(), + E = FTy->param_end(); I != E; ++I) { + const Type *ArgTy = *I; + if (PAL.paramHasAttr(Idx, Attribute::ByVal)) { + assert(isa(ArgTy)); + ArgTy = cast(ArgTy)->getElementType(); + } + if (I != FTy->param_begin()) + FunctionInnards << ", "; + printType(FunctionInnards, ArgTy, + /*isSigned=*/PAL.paramHasAttr(Idx, Attribute::SExt), ""); + ++Idx; + } + if (FTy->isVarArg()) { + if (FTy->getNumParams()) + FunctionInnards << ", ..."; + } else if (!FTy->getNumParams()) { + FunctionInnards << "void"; + } + FunctionInnards << ')'; + std::string tstr = FunctionInnards.str(); + printType(Out, FTy->getReturnType(), + /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), tstr); + return Out; + } + case Type::StructTyID: { + const StructType *STy = cast(Ty); + Out << NameSoFar + " {\n"; + unsigned Idx = 0; + for (StructType::element_iterator I = STy->element_begin(), + E = STy->element_end(); I != E; ++I) { + Out << " "; + printType(Out, *I, false, "field" + utostr(Idx++)); + Out << ";\n"; + } + Out << '}'; + if (STy->isPacked()) + Out << " __attribute__ ((packed))"; + return Out; + } + + case Type::PointerTyID: { + const PointerType *PTy = cast(Ty); + std::string ptrName = "*" + NameSoFar; + + if (isa(PTy->getElementType()) || + isa(PTy->getElementType())) + ptrName = "(" + ptrName + ")"; + + if (!PAL.isEmpty()) + // Must be a function ptr cast! + return printType(Out, PTy->getElementType(), false, ptrName, true, PAL); + return printType(Out, PTy->getElementType(), false, ptrName); } + + case Type::ArrayTyID: { + const ArrayType *ATy = cast(Ty); + unsigned NumElements = ATy->getNumElements(); + if (NumElements == 0) NumElements = 1; + // Arrays are wrapped in structs to allow them to have normal + // value semantics (avoiding the array "decay"). + Out << NameSoFar << " { "; + printType(Out, ATy->getElementType(), false, + "array[" + utostr(NumElements) + "]"); + return Out << "; }"; + } + + case Type::OpaqueTyID: { + std::string TyName = "struct opaque_" + itostr(OpaqueCounter++); + assert(TypeNames.find(Ty) == TypeNames.end()); + TypeNames[Ty] = TyName; + return Out << TyName << ' ' << NameSoFar; + } + default: + llvm_unreachable("Unhandled case in getTypeProps!"); + } + + return Out; } // Pass the Type* and the variable name and this prints out the variable @@ -479,7 +670,7 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned, // std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, bool isSigned, const std::string &NameSoFar, - bool IgnoreName, const PAListPtr &PAL) { + bool IgnoreName, const AttrListPtr &PAL) { if (Ty->isPrimitiveType() || Ty->isInteger() || isa(Ty)) { printSimpleType(Out, Ty, isSigned, NameSoFar); return Out; @@ -500,14 +691,14 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { const Type *ArgTy = *I; - if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) { + if (PAL.paramHasAttr(Idx, Attribute::ByVal)) { assert(isa(ArgTy)); ArgTy = cast(ArgTy)->getElementType(); } if (I != FTy->param_begin()) FunctionInnards << ", "; printType(FunctionInnards, ArgTy, - /*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt), ""); + /*isSigned=*/PAL.paramHasAttr(Idx, Attribute::SExt), ""); ++Idx; } if (FTy->isVarArg()) { @@ -519,7 +710,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, FunctionInnards << ')'; std::string tstr = FunctionInnards.str(); printType(Out, FTy->getReturnType(), - /*isSigned=*/PAL.paramHasAttr(0, ParamAttr::SExt), tstr); + /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), tstr); return Out; } case Type::StructTyID: { @@ -556,26 +747,28 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, const ArrayType *ATy = cast(Ty); unsigned NumElements = ATy->getNumElements(); if (NumElements == 0) NumElements = 1; - return printType(Out, ATy->getElementType(), false, - NameSoFar + "[" + utostr(NumElements) + "]"); + // Arrays are wrapped in structs to allow them to have normal + // value semantics (avoiding the array "decay"). + Out << NameSoFar << " { "; + printType(Out, ATy->getElementType(), false, + "array[" + utostr(NumElements) + "]"); + return Out << "; }"; } case Type::OpaqueTyID: { - static int Count = 0; - std::string TyName = "struct opaque_" + itostr(Count++); + std::string TyName = "struct opaque_" + itostr(OpaqueCounter++); assert(TypeNames.find(Ty) == TypeNames.end()); TypeNames[Ty] = TyName; return Out << TyName << ' ' << NameSoFar; } default: - assert(0 && "Unhandled case in getTypeProps!"); - abort(); + llvm_unreachable("Unhandled case in getTypeProps!"); } return Out; } -void CWriter::printConstantArray(ConstantArray *CPA) { +void CWriter::printConstantArray(ConstantArray *CPA, bool Static) { // As a special case, print the array as a string if it is an array of // ubytes or an array of sbytes with positive values. @@ -606,9 +799,9 @@ void CWriter::printConstantArray(ConstantArray *CPA) { if (isprint(C) && (!LastWasHex || !isxdigit(C))) { LastWasHex = false; if (C == '"' || C == '\\') - Out << "\\" << C; + Out << "\\" << (char)C; else - Out << C; + Out << (char)C; } else { LastWasHex = false; switch (C) { @@ -633,24 +826,24 @@ void CWriter::printConstantArray(ConstantArray *CPA) { Out << '{'; if (CPA->getNumOperands()) { Out << ' '; - printConstant(cast(CPA->getOperand(0))); + printConstant(cast(CPA->getOperand(0)), Static); for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) { Out << ", "; - printConstant(cast(CPA->getOperand(i))); + printConstant(cast(CPA->getOperand(i)), Static); } } Out << " }"; } } -void CWriter::printConstantVector(ConstantVector *CP) { +void CWriter::printConstantVector(ConstantVector *CP, bool Static) { Out << '{'; if (CP->getNumOperands()) { Out << ' '; - printConstant(cast(CP->getOperand(0))); + printConstant(cast(CP->getOperand(0)), Static); for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { Out << ", "; - printConstant(cast(CP->getOperand(i))); + printConstant(cast(CP->getOperand(i)), Static); } } Out << " }"; @@ -665,12 +858,13 @@ void CWriter::printConstantVector(ConstantVector *CP) { // only deal in IEEE FP). // static bool isFPCSafeToPrint(const ConstantFP *CFP) { + bool ignored; // Do long doubles in hex for now. - if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy) + if (CFP->getType() != Type::FloatTy && CFP->getType() != Type::DoubleTy) return false; APFloat APF = APFloat(CFP->getValueAPF()); // copy - if (CFP->getType()==Type::FloatTy) - APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven); + if (CFP->getType() == Type::FloatTy) + APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A char Buffer[100]; sprintf(Buffer, "%a", APF.convertToDouble()); @@ -727,7 +921,7 @@ void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) { Out << ')'; break; default: - assert(0 && "Invalid cast opcode"); + llvm_unreachable("Invalid cast opcode"); } // Print the source type cast @@ -757,13 +951,13 @@ void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) { case Instruction::FPToUI: break; // These don't need a source cast. default: - assert(0 && "Invalid cast opcode"); + llvm_unreachable("Invalid cast opcode"); break; } } // printConstant - The LLVM Constant to C Constant converter. -void CWriter::printConstant(Constant *CPV) { +void CWriter::printConstant(Constant *CPV, bool Static) { if (const ConstantExpr *CE = dyn_cast(CPV)) { switch (CE->getOpcode()) { case Instruction::Trunc: @@ -785,7 +979,7 @@ void CWriter::printConstant(Constant *CPV) { // Make sure we really sext from bool here by subtracting from 0 Out << "0-"; } - printConstant(CE->getOperand(0)); + printConstant(CE->getOperand(0), Static); if (CE->getType() == Type::Int1Ty && (CE->getOpcode() == Instruction::Trunc || CE->getOpcode() == Instruction::FPToUI || @@ -800,21 +994,24 @@ void CWriter::printConstant(Constant *CPV) { case Instruction::GetElementPtr: Out << "("; printGEPExpression(CE->getOperand(0), gep_type_begin(CPV), - gep_type_end(CPV)); + gep_type_end(CPV), Static); Out << ")"; return; case Instruction::Select: Out << '('; - printConstant(CE->getOperand(0)); + printConstant(CE->getOperand(0), Static); Out << '?'; - printConstant(CE->getOperand(1)); + printConstant(CE->getOperand(1), Static); Out << ':'; - printConstant(CE->getOperand(2)); + printConstant(CE->getOperand(2), Static); Out << ')'; return; case Instruction::Add: + case Instruction::FAdd: case Instruction::Sub: + case Instruction::FSub: case Instruction::Mul: + case Instruction::FMul: case Instruction::SDiv: case Instruction::UDiv: case Instruction::FDiv: @@ -830,12 +1027,15 @@ void CWriter::printConstant(Constant *CPV) { case Instruction::AShr: { Out << '('; - bool NeedsClosingParens = printConstExprCast(CE); + bool NeedsClosingParens = printConstExprCast(CE, Static); printConstantWithCast(CE->getOperand(0), CE->getOpcode()); switch (CE->getOpcode()) { - case Instruction::Add: Out << " + "; break; - case Instruction::Sub: Out << " - "; break; - case Instruction::Mul: Out << " * "; break; + case Instruction::Add: + case Instruction::FAdd: Out << " + "; break; + case Instruction::Sub: + case Instruction::FSub: Out << " - "; break; + case Instruction::Mul: + case Instruction::FMul: Out << " * "; break; case Instruction::URem: case Instruction::SRem: case Instruction::FRem: Out << " % "; break; @@ -860,10 +1060,10 @@ void CWriter::printConstant(Constant *CPV) { case ICmpInst::ICMP_UGT: Out << " > "; break; case ICmpInst::ICMP_SGE: case ICmpInst::ICMP_UGE: Out << " >= "; break; - default: assert(0 && "Illegal ICmp predicate"); + default: llvm_unreachable("Illegal ICmp predicate"); } break; - default: assert(0 && "Illegal opcode here!"); + default: llvm_unreachable("Illegal opcode here!"); } printConstantWithCast(CE->getOperand(1), CE->getOpcode()); if (NeedsClosingParens) @@ -873,7 +1073,7 @@ void CWriter::printConstant(Constant *CPV) { } case Instruction::FCmp: { Out << '('; - bool NeedsClosingParens = printConstExprCast(CE); + bool NeedsClosingParens = printConstExprCast(CE, Static); if (CE->getPredicate() == FCmpInst::FCMP_FALSE) Out << "0"; else if (CE->getPredicate() == FCmpInst::FCMP_TRUE) @@ -881,7 +1081,7 @@ void CWriter::printConstant(Constant *CPV) { else { const char* op = 0; switch (CE->getPredicate()) { - default: assert(0 && "Illegal FCmp predicate"); + default: llvm_unreachable("Illegal FCmp predicate"); case FCmpInst::FCMP_ORD: op = "ord"; break; case FCmpInst::FCMP_UNO: op = "uno"; break; case FCmpInst::FCMP_UEQ: op = "ueq"; break; @@ -909,11 +1109,13 @@ void CWriter::printConstant(Constant *CPV) { return; } default: +#ifndef NDEBUG cerr << "CWriter Error: Unhandled constant expression: " << *CE << "\n"; - abort(); +#endif + llvm_unreachable(0); } - } else if (isa(CPV) && CPV->getType()->isFirstClassType()) { + } else if (isa(CPV) && CPV->getType()->isSingleValueType()) { Out << "(("; printType(Out, CPV->getType()); // sign doesn't matter Out << ")/*UNDEF*/"; @@ -940,7 +1142,7 @@ void CWriter::printConstant(Constant *CPV) { Out << CI->getZExtValue() << 'u'; else Out << CI->getSExtValue(); - Out << ')'; + Out << ')'; } return; } @@ -961,11 +1163,21 @@ void CWriter::printConstant(Constant *CPV) { "long double") << "*)&FPConstant" << I->second << ')'; } else { - assert(FPC->getType() == Type::FloatTy || - FPC->getType() == Type::DoubleTy); - double V = FPC->getType() == Type::FloatTy ? - FPC->getValueAPF().convertToFloat() : - FPC->getValueAPF().convertToDouble(); + double V; + if (FPC->getType() == Type::FloatTy) + V = FPC->getValueAPF().convertToFloat(); + else if (FPC->getType() == Type::DoubleTy) + V = FPC->getValueAPF().convertToDouble(); + else { + // Long double. Convert the number to double, discarding precision. + // This is not awesome, but it at least makes the CBE output somewhat + // useful. + APFloat Tmp = FPC->getValueAPF(); + bool LosesInfo; + Tmp.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &LosesInfo); + V = Tmp.convertToDouble(); + } + if (IsNAN(V)) { // The value is NaN @@ -1012,56 +1224,72 @@ void CWriter::printConstant(Constant *CPV) { } case Type::ArrayTyID: + // Use C99 compound expression literal initializer syntax. + if (!Static) { + Out << "("; + printType(Out, CPV->getType()); + Out << ")"; + } + Out << "{ "; // Arrays are wrapped in struct types. if (ConstantArray *CA = dyn_cast(CPV)) { - printConstantArray(CA); + printConstantArray(CA, Static); } else { assert(isa(CPV) || isa(CPV)); const ArrayType *AT = cast(CPV->getType()); Out << '{'; if (AT->getNumElements()) { Out << ' '; - Constant *CZ = Constant::getNullValue(AT->getElementType()); - printConstant(CZ); + Constant *CZ = Context->getNullValue(AT->getElementType()); + printConstant(CZ, Static); for (unsigned i = 1, e = AT->getNumElements(); i != e; ++i) { Out << ", "; - printConstant(CZ); + printConstant(CZ, Static); } } Out << " }"; } + Out << " }"; // Arrays are wrapped in struct types. break; case Type::VectorTyID: // Use C99 compound expression literal initializer syntax. - Out << "("; - printType(Out, CPV->getType()); - Out << ")"; + if (!Static) { + Out << "("; + printType(Out, CPV->getType()); + Out << ")"; + } if (ConstantVector *CV = dyn_cast(CPV)) { - printConstantVector(CV); + printConstantVector(CV, Static); } else { assert(isa(CPV) || isa(CPV)); const VectorType *VT = cast(CPV->getType()); Out << "{ "; - Constant *CZ = Constant::getNullValue(VT->getElementType()); - printConstant(CZ); + Constant *CZ = Context->getNullValue(VT->getElementType()); + printConstant(CZ, Static); for (unsigned i = 1, e = VT->getNumElements(); i != e; ++i) { Out << ", "; - printConstant(CZ); + printConstant(CZ, Static); } Out << " }"; } break; case Type::StructTyID: + // Use C99 compound expression literal initializer syntax. + if (!Static) { + Out << "("; + printType(Out, CPV->getType()); + Out << ")"; + } if (isa(CPV) || isa(CPV)) { const StructType *ST = cast(CPV->getType()); Out << '{'; if (ST->getNumElements()) { Out << ' '; - printConstant(Constant::getNullValue(ST->getElementType(0))); + printConstant(Context->getNullValue(ST->getElementType(0)), Static); for (unsigned i = 1, e = ST->getNumElements(); i != e; ++i) { Out << ", "; - printConstant(Constant::getNullValue(ST->getElementType(i))); + printConstant(Context->getNullValue(ST->getElementType(i)), Static); } } Out << " }"; @@ -1069,10 +1297,10 @@ void CWriter::printConstant(Constant *CPV) { Out << '{'; if (CPV->getNumOperands()) { Out << ' '; - printConstant(cast(CPV->getOperand(0))); + printConstant(cast(CPV->getOperand(0)), Static); for (unsigned i = 1, e = CPV->getNumOperands(); i != e; ++i) { Out << ", "; - printConstant(cast(CPV->getOperand(i))); + printConstant(cast(CPV->getOperand(i)), Static); } } Out << " }"; @@ -1086,24 +1314,31 @@ void CWriter::printConstant(Constant *CPV) { Out << ")/*NULL*/0)"; break; } else if (GlobalValue *GV = dyn_cast(CPV)) { - writeOperand(GV); + writeOperand(GV, Static); break; } // FALL THROUGH default: +#ifndef NDEBUG cerr << "Unknown constant type: " << *CPV << "\n"; - abort(); +#endif + llvm_unreachable(0); } } // Some constant expressions need to be casted back to the original types // because their operands were casted to the expected type. This function takes // care of detecting that case and printing the cast for the ConstantExpr. -bool CWriter::printConstExprCast(const ConstantExpr* CE) { +bool CWriter::printConstExprCast(const ConstantExpr* CE, bool Static) { bool NeedsExplicitCast = false; const Type *Ty = CE->getOperand(0)->getType(); bool TypeIsSigned = false; switch (CE->getOpcode()) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + // We need to cast integer arithmetic so that it is always performed + // as unsigned, to avoid undefined behavior on overflow. case Instruction::LShr: case Instruction::URem: case Instruction::UDiv: NeedsExplicitCast = true; break; @@ -1162,6 +1397,11 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { default: // for most instructions, it doesn't matter break; + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + // We need to cast integer arithmetic so that it is always performed + // as unsigned, to avoid undefined behavior on overflow. case Instruction::LShr: case Instruction::UDiv: case Instruction::URem: @@ -1181,48 +1421,81 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { Out << "(("; printSimpleType(Out, OpTy, typeIsSigned); Out << ")"; - printConstant(CPV); + printConstant(CPV, false); Out << ")"; } else - printConstant(CPV); + printConstant(CPV, false); } std::string CWriter::GetValueName(const Value *Operand) { - std::string Name; - - if (!isa(Operand) && Operand->getName() != "") { - std::string VarName; - - Name = Operand->getName(); - VarName.reserve(Name.capacity()); - - for (std::string::iterator I = Name.begin(), E = Name.end(); - I != E; ++I) { - char ch = *I; - - if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || ch == '_')) { - char buffer[5]; - sprintf(buffer, "_%x_", ch); - VarName += buffer; - } else - VarName += ch; - } - - Name = "llvm_cbe_" + VarName; - } else { - Name = Mang->getValueName(Operand); + // Mangle globals with the standard mangler interface for LLC compatibility. + if (const GlobalValue *GV = dyn_cast(Operand)) + return Mang->getMangledName(GV); + + std::string Name = Operand->getName(); + + if (Name.empty()) { // Assign unique names to local temporaries. + unsigned &No = AnonValueNumbers[Operand]; + if (No == 0) + No = ++NextAnonValueNumber; + Name = "tmp__" + utostr(No); } + + std::string VarName; + VarName.reserve(Name.capacity()); - return Name; + for (std::string::iterator I = Name.begin(), E = Name.end(); + I != E; ++I) { + char ch = *I; + + if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || ch == '_')) { + char buffer[5]; + sprintf(buffer, "_%x_", ch); + VarName += buffer; + } else + VarName += ch; + } + + return "llvm_cbe_" + VarName; +} + +/// writeInstComputationInline - Emit the computation for the specified +/// instruction inline, with no destination provided. +void CWriter::writeInstComputationInline(Instruction &I) { + // We can't currently support integer types other than 1, 8, 16, 32, 64. + // Validate this. + const Type *Ty = I.getType(); + if (Ty->isInteger() && (Ty!=Type::Int1Ty && Ty!=Type::Int8Ty && + Ty!=Type::Int16Ty && Ty!=Type::Int32Ty && Ty!=Type::Int64Ty)) { + llvm_report_error("The C backend does not currently support integer " + "types of widths other than 1, 8, 16, 32, 64.\n" + "This is being tracked as PR 4158."); + } + + // If this is a non-trivial bool computation, make sure to truncate down to + // a 1 bit value. This is important because we want "add i1 x, y" to return + // "0" when x and y are true, not "2" for example. + bool NeedBoolTrunc = false; + if (I.getType() == Type::Int1Ty && !isa(I) && !isa(I)) + NeedBoolTrunc = true; + + if (NeedBoolTrunc) + Out << "(("; + + visit(I); + + if (NeedBoolTrunc) + Out << ")&1)"; } -void CWriter::writeOperandInternal(Value *Operand) { + +void CWriter::writeOperandInternal(Value *Operand, bool Static) { if (Instruction *I = dyn_cast(Operand)) + // Should we inline this instruction to build a tree? if (isInlinableInst(*I) && !isDirectAlloca(I)) { - // Should we inline this instruction to build a tree? Out << '('; - visit(*I); + writeInstComputationInline(*I); Out << ')'; return; } @@ -1230,26 +1503,17 @@ void CWriter::writeOperandInternal(Value *Operand) { Constant* CPV = dyn_cast(Operand); if (CPV && !isa(CPV)) - printConstant(CPV); + printConstant(CPV, Static); else Out << GetValueName(Operand); } -void CWriter::writeOperandRaw(Value *Operand) { - Constant* CPV = dyn_cast(Operand); - if (CPV && !isa(CPV)) { - printConstant(CPV); - } else { - Out << GetValueName(Operand); - } -} - -void CWriter::writeOperand(Value *Operand) { +void CWriter::writeOperand(Value *Operand, bool Static) { bool isAddressImplicit = isAddressExposed(Operand); if (isAddressImplicit) Out << "(&"; // Global variables are referenced as their addresses by llvm - writeOperandInternal(Operand); + writeOperandInternal(Operand, Static); if (isAddressImplicit) Out << ')'; @@ -1262,6 +1526,11 @@ void CWriter::writeOperand(Value *Operand) { bool CWriter::writeInstructionCast(const Instruction &I) { const Type *Ty = I.getOperand(0)->getType(); switch (I.getOpcode()) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + // We need to cast integer arithmetic so that it is always performed + // as unsigned, to avoid undefined behavior on overflow. case Instruction::LShr: case Instruction::URem: case Instruction::UDiv: @@ -1302,6 +1571,11 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) { default: // for most instructions, it doesn't matter break; + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + // We need to cast integer arithmetic so that it is always performed + // as unsigned, to avoid undefined behavior on overflow. case Instruction::LShr: case Instruction::UDiv: case Instruction::URem: // Cast to unsigned first @@ -1364,7 +1638,7 @@ void CWriter::writeOperandWithCast(Value* Operand, const ICmpInst &Cmp) { // generateCompilerSpecificCode - This is where we add conditional compilation // directives to cater to specific compilers as need be. // -static void generateCompilerSpecificCode(std::ostream& Out, +static void generateCompilerSpecificCode(formatted_raw_ostream& Out, const TargetData *TD) { // Alloca is hard to get, and we don't want to include stdlib.h here. Out << "/* get a declaration for alloca */\n" @@ -1383,7 +1657,7 @@ static void generateCompilerSpecificCode(std::ostream& Out, << "extern void *__builtin_alloca(unsigned int);\n" << "#endif\n" << "#define alloca(x) __builtin_alloca(x)\n" - << "#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)\n" + << "#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)\n" << "#define alloca(x) __builtin_alloca(x)\n" << "#elif defined(_MSC_VER)\n" << "#define inline _inline\n" @@ -1485,12 +1759,10 @@ static void generateCompilerSpecificCode(std::ostream& Out, // Output typedefs for 128-bit integers. If these are needed with a // 32-bit target or with a C compiler that doesn't support mode(TI), // more drastic measures will be needed. - if (TD->getPointerSize() >= 8) { - Out << "#ifdef __GNUC__ /* 128-bit integer types */\n" - << "typedef int __attribute__((mode(TI))) llvmInt128;\n" - << "typedef unsigned __attribute__((mode(TI))) llvmUInt128;\n" - << "#endif\n\n"; - } + Out << "#if __GNUC__ && __LP64__ /* 128-bit integer types */\n" + << "typedef int __attribute__((mode(TI))) llvmInt128;\n" + << "typedef unsigned __attribute__((mode(TI))) llvmUInt128;\n" + << "#endif\n\n"; // Output target-specific code that should be inserted into main. Out << "#define CODE_FOR_MAIN() /* Any target-specific code for main()*/\n"; @@ -1665,7 +1937,7 @@ bool CWriter::doInitialization(Module &M) { if (getGlobalVariableClass(I)) continue; - if (I->hasInternalLinkage()) + if (I->hasLocalLinkage()) Out << "static "; else Out << "extern "; @@ -1701,7 +1973,7 @@ bool CWriter::doInitialization(Module &M) { if (getGlobalVariableClass(I)) continue; - if (I->hasInternalLinkage()) + if (I->hasLocalLinkage()) Out << "static "; else if (I->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; @@ -1732,19 +2004,22 @@ bool CWriter::doInitialization(Module &M) { // FIXME common linkage should avoid this problem. if (!I->getInitializer()->isNullValue()) { Out << " = " ; - writeOperand(I->getInitializer()); + writeOperand(I->getInitializer(), true); } else if (I->hasWeakLinkage()) { // We have to specify an initializer, but it doesn't have to be // complete. If the value is an aggregate, print out { 0 }, and let // the compiler figure out the rest of the zeros. Out << " = " ; if (isa(I->getInitializer()->getType()) || - isa(I->getInitializer()->getType()) || isa(I->getInitializer()->getType())) { Out << "{ 0 }"; + } else if (isa(I->getInitializer()->getType())) { + // As with structs and vectors, but with an extra set of braces + // because arrays are wrapped in structs. + Out << "{ { 0 } }"; } else { // Just print it out normally. - writeOperand(I->getInitializer()); + writeOperand(I->getInitializer(), true); } } Out << ";\n"; @@ -1795,51 +2070,67 @@ void CWriter::printFloatingPointConstants(Function &F) { // the precision of the printed form, unless the printed form preserves // precision. // - static unsigned FPCounter = 0; for (constant_iterator I = constant_begin(&F), E = constant_end(&F); I != E; ++I) - if (const ConstantFP *FPC = dyn_cast(*I)) - if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. - !FPConstantMap.count(FPC)) { - FPConstantMap[FPC] = FPCounter; // Number the FP constants - - if (FPC->getType() == Type::DoubleTy) { - double Val = FPC->getValueAPF().convertToDouble(); - uint64_t i = FPC->getValueAPF().convertToAPInt().getZExtValue(); - Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << i << std::dec - << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { - float Val = FPC->getValueAPF().convertToFloat(); - uint32_t i = (uint32_t)FPC->getValueAPF().convertToAPInt(). - getZExtValue(); - Out << "static const ConstantFloatTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << i << std::dec - << "U; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::X86_FP80Ty) { - // api needed to prevent premature destruction - APInt api = FPC->getValueAPF().convertToAPInt(); - const uint64_t *p = api.getRawData(); - Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ - << " = { 0x" << std::hex - << ((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16) - << ", 0x" << (uint16_t)(p[0] >> 48) << ",0,0,0" - << "}; /* Long double constant */\n" << std::dec; - } else if (FPC->getType() == Type::PPC_FP128Ty) { - APInt api = FPC->getValueAPF().convertToAPInt(); - const uint64_t *p = api.getRawData(); - Out << "static const ConstantFP128Ty FPConstant" << FPCounter++ - << " = { 0x" << std::hex - << p[0] << ", 0x" << p[1] - << "}; /* Long double constant */\n" << std::dec; - - } else - assert(0 && "Unknown float type!"); - } + printFloatingPointConstants(*I); Out << '\n'; } +void CWriter::printFloatingPointConstants(const Constant *C) { + // If this is a constant expression, recursively check for constant fp values. + if (const ConstantExpr *CE = dyn_cast(C)) { + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) + printFloatingPointConstants(CE->getOperand(i)); + return; + } + + // Otherwise, check for a FP constant that we need to print. + const ConstantFP *FPC = dyn_cast(C); + if (FPC == 0 || + // Do not put in FPConstantMap if safe. + isFPCSafeToPrint(FPC) || + // Already printed this constant? + FPConstantMap.count(FPC)) + return; + + FPConstantMap[FPC] = FPCounter; // Number the FP constants + + if (FPC->getType() == Type::DoubleTy) { + double Val = FPC->getValueAPF().convertToDouble(); + uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue(); + Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ + << " = 0x" << utohexstr(i) + << "ULL; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::FloatTy) { + float Val = FPC->getValueAPF().convertToFloat(); + uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt(). + getZExtValue(); + Out << "static const ConstantFloatTy FPConstant" << FPCounter++ + << " = 0x" << utohexstr(i) + << "U; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::X86_FP80Ty) { + // api needed to prevent premature destruction + APInt api = FPC->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ + << " = { 0x" << utohexstr(p[0]) + << "ULL, 0x" << utohexstr((uint16_t)p[1]) << ",{0,0,0}" + << "}; /* Long double constant */\n"; + } else if (FPC->getType() == Type::PPC_FP128Ty) { + APInt api = FPC->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Out << "static const ConstantFP128Ty FPConstant" << FPCounter++ + << " = { 0x" + << utohexstr(p[0]) << ", 0x" << utohexstr(p[1]) + << "}; /* Long double constant */\n"; + + } else { + llvm_unreachable("Unknown float type!"); + } +} + + /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit its declaration... @@ -1883,16 +2174,16 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { Out << '\n'; // Keep track of which structures have been printed so far... - std::set StructPrinted; + std::set StructPrinted; // Loop over all structures then push them into the stack so they are // printed in the correct order. // Out << "/* Structure contents */\n"; for (I = TST.begin(); I != End; ++I) - if (const StructType *STy = dyn_cast(I->second)) + if (isa(I->second) || isa(I->second)) // Only print out used types! - printContainedStructs(STy, StructPrinted); + printContainedStructs(I->second, StructPrinted); } // Push the struct onto the stack and recursively push all structs @@ -1901,7 +2192,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { // TODO: Make this work properly with vector types // void CWriter::printContainedStructs(const Type *Ty, - std::set &StructPrinted){ + std::set &StructPrinted) { // Don't walk through pointers. if (isa(Ty) || Ty->isPrimitiveType() || Ty->isInteger()) return; @@ -1910,12 +2201,12 @@ void CWriter::printContainedStructs(const Type *Ty, E = Ty->subtype_end(); I != E; ++I) printContainedStructs(*I, StructPrinted); - if (const StructType *STy = dyn_cast(Ty)) { + if (isa(Ty) || isa(Ty)) { // Check to see if we have already printed this struct. - if (StructPrinted.insert(STy).second) { + if (StructPrinted.insert(Ty).second) { // Print structure type out. - std::string Name = TypeNames[STy]; - printType(Out, STy, false, Name, true); + std::string Name = TypeNames[Ty]; + printType(Out, Ty, false, Name, true); Out << ";\n\n"; } } @@ -1925,21 +2216,21 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { /// isStructReturn - Should this function actually return a struct by-value? bool isStructReturn = F->hasStructRetAttr(); - if (F->hasInternalLinkage()) Out << "static "; + if (F->hasLocalLinkage()) Out << "static "; if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) "; switch (F->getCallingConv()) { case CallingConv::X86_StdCall: - Out << "__stdcall "; + Out << "__attribute__((stdcall)) "; break; case CallingConv::X86_FastCall: - Out << "__fastcall "; + Out << "__attribute__((fastcall)) "; break; } // Loop over the arguments, printing them... const FunctionType *FT = cast(F->getFunctionType()); - const PAListPtr &PAL = F->getParamAttrs(); + const AttrListPtr &PAL = F->getAttributes(); std::stringstream FunctionInnards; @@ -1968,12 +2259,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { else ArgName = ""; const Type *ArgTy = I->getType(); - if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) { + if (PAL.paramHasAttr(Idx, Attribute::ByVal)) { ArgTy = cast(ArgTy)->getElementType(); ByValParams.insert(I); } printType(FunctionInnards, ArgTy, - /*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt), + /*isSigned=*/PAL.paramHasAttr(Idx, Attribute::SExt), ArgName); PrintedArg = true; ++Idx; @@ -1995,12 +2286,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { for (; I != E; ++I) { if (PrintedArg) FunctionInnards << ", "; const Type *ArgTy = *I; - if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) { + if (PAL.paramHasAttr(Idx, Attribute::ByVal)) { assert(isa(ArgTy)); ArgTy = cast(ArgTy)->getElementType(); } printType(FunctionInnards, ArgTy, - /*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt)); + /*isSigned=*/PAL.paramHasAttr(Idx, Attribute::SExt)); PrintedArg = true; ++Idx; } @@ -2028,7 +2319,7 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { // Print out the return type and the signature built above. printType(Out, RetTy, - /*isSigned=*/PAL.paramHasAttr(0, ParamAttr::SExt), + /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), FunctionInnards.str()); } @@ -2152,12 +2443,12 @@ void CWriter::printBasicBlock(BasicBlock *BB) { outputLValue(II); else Out << " "; - visit(*II); + writeInstComputationInline(*II); Out << ";\n"; } } - // Don't emit prefix or suffix for the terminator... + // Don't emit prefix or suffix for the terminator. visit(*BB->getTerminator()); } @@ -2337,6 +2628,10 @@ void CWriter::visitBinaryOperator(Instruction &I) { Out << "-("; writeOperand(BinaryOperator::getNegArgument(cast(&I))); Out << ")"; + } else if (BinaryOperator::isFNeg(&I)) { + Out << "-("; + writeOperand(BinaryOperator::getFNegArgument(cast(&I))); + Out << ")"; } else if (I.getOpcode() == Instruction::FRem) { // Output a call to fmod/fmodf instead of emitting a%b if (I.getType() == Type::FloatTy) @@ -2361,9 +2656,12 @@ void CWriter::visitBinaryOperator(Instruction &I) { writeOperandWithCast(I.getOperand(0), I.getOpcode()); switch (I.getOpcode()) { - case Instruction::Add: Out << " + "; break; - case Instruction::Sub: Out << " - "; break; - case Instruction::Mul: Out << " * "; break; + case Instruction::Add: + case Instruction::FAdd: Out << " + "; break; + case Instruction::Sub: + case Instruction::FSub: Out << " - "; break; + case Instruction::Mul: + case Instruction::FMul: Out << " * "; break; case Instruction::URem: case Instruction::SRem: case Instruction::FRem: Out << " % "; break; @@ -2376,7 +2674,11 @@ void CWriter::visitBinaryOperator(Instruction &I) { case Instruction::Shl : Out << " << "; break; case Instruction::LShr: case Instruction::AShr: Out << " >> "; break; - default: cerr << "Invalid operator type!" << I; abort(); + default: +#ifndef NDEBUG + cerr << "Invalid operator type!" << I; +#endif + llvm_unreachable(0); } writeOperandWithCast(I.getOperand(1), I.getOpcode()); @@ -2413,7 +2715,11 @@ void CWriter::visitICmpInst(ICmpInst &I) { case ICmpInst::ICMP_SLT: Out << " < "; break; case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: Out << " > "; break; - default: cerr << "Invalid icmp predicate!" << I; abort(); + default: +#ifndef NDEBUG + cerr << "Invalid icmp predicate!" << I; +#endif + llvm_unreachable(0); } writeOperandWithCast(I.getOperand(1), I); @@ -2437,7 +2743,7 @@ void CWriter::visitFCmpInst(FCmpInst &I) { const char* op = 0; switch (I.getPredicate()) { - default: assert(0 && "Illegal FCmp predicate"); + default: llvm_unreachable("Illegal FCmp predicate"); case FCmpInst::FCMP_ORD: op = "ord"; break; case FCmpInst::FCMP_UNO: op = "uno"; break; case FCmpInst::FCMP_UEQ: op = "ueq"; break; @@ -2465,7 +2771,7 @@ void CWriter::visitFCmpInst(FCmpInst &I) { static const char * getFloatBitCastField(const Type *Ty) { switch (Ty->getTypeID()) { - default: assert(0 && "Invalid Type"); + default: llvm_unreachable("Invalid Type"); case Type::FloatTyID: return "Float"; case Type::DoubleTyID: return "Double"; case Type::IntegerTyID: { @@ -2481,29 +2787,34 @@ static const char * getFloatBitCastField(const Type *Ty) { void CWriter::visitCastInst(CastInst &I) { const Type *DstTy = I.getType(); const Type *SrcTy = I.getOperand(0)->getType(); - Out << '('; if (isFPIntBitCast(I)) { + Out << '('; // These int<->float and long<->double casts need to be handled specially Out << GetValueName(&I) << "__BITCAST_TEMPORARY." << getFloatBitCastField(I.getOperand(0)->getType()) << " = "; writeOperand(I.getOperand(0)); Out << ", " << GetValueName(&I) << "__BITCAST_TEMPORARY." << getFloatBitCastField(I.getType()); - } else { - printCast(I.getOpcode(), SrcTy, DstTy); - if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) { - // Make sure we really get a sext from bool by subtracing the bool from 0 - Out << "0-"; - } - writeOperand(I.getOperand(0)); - if (DstTy == Type::Int1Ty && - (I.getOpcode() == Instruction::Trunc || - I.getOpcode() == Instruction::FPToUI || - I.getOpcode() == Instruction::FPToSI || - I.getOpcode() == Instruction::PtrToInt)) { - // Make sure we really get a trunc to bool by anding the operand with 1 - Out << "&1u"; - } + Out << ')'; + return; + } + + Out << '('; + printCast(I.getOpcode(), SrcTy, DstTy); + + // Make a sext from i1 work by subtracting the i1 from 0 (an int). + if (SrcTy == Type::Int1Ty && I.getOpcode() == Instruction::SExt) + Out << "0-"; + + writeOperand(I.getOperand(0)); + + if (DstTy == Type::Int1Ty && + (I.getOpcode() == Instruction::Trunc || + I.getOpcode() == Instruction::FPToUI || + I.getOpcode() == Instruction::FPToSI || + I.getOpcode() == Instruction::PtrToInt)) { + // Make sure we really get a trunc to bool by anding the operand with 1 + Out << "&1u"; } Out << ')'; } @@ -2616,7 +2927,7 @@ void CWriter::visitCallInst(CallInst &I) { // If this is a call to a struct-return function, assign to the first // parameter instead of passing it to the call. - const PAListPtr &PAL = I.getParamAttrs(); + const AttrListPtr &PAL = I.getAttributes(); bool hasByVal = I.hasByValArgument(); bool isStructRet = I.hasStructRetAttr(); if (isStructRet) { @@ -2684,11 +2995,11 @@ void CWriter::visitCallInst(CallInst &I) { (*AI)->getType() != FTy->getParamType(ArgNo)) { Out << '('; printType(Out, FTy->getParamType(ArgNo), - /*isSigned=*/PAL.paramHasAttr(ArgNo+1, ParamAttr::SExt)); + /*isSigned=*/PAL.paramHasAttr(ArgNo+1, Attribute::SExt)); Out << ')'; } // Check if the argument is expected to be passed by value. - if (I.paramHasAttr(ArgNo+1, ParamAttr::ByVal)) + if (I.paramHasAttr(ArgNo+1, Attribute::ByVal)) writeOperandDeref(*AI); else writeOperand(*AI); @@ -2728,10 +3039,12 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, Out << ", "; // Output the last argument to the enclosing function. if (I.getParent()->getParent()->arg_empty()) { - cerr << "The C backend does not currently support zero " + std::string msg; + raw_string_ostream Msg(msg); + Msg << "The C backend does not currently support zero " << "argument varargs functions, such as '" - << I.getParent()->getParent()->getName() << "'!\n"; - abort(); + << I.getParent()->getParent()->getName() << "'!"; + llvm_report_error(Msg.str()); } writeOperand(--I.getParent()->getParent()->arg_end()); Out << ')'; @@ -2800,11 +3113,16 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, case Intrinsic::dbg_stoppoint: { // If we use writeOperand directly we get a "u" suffix which is rejected // by gcc. + std::stringstream SPIStr; DbgStopPointInst &SPI = cast(I); + SPI.getDirectory()->print(SPIStr); Out << "\n#line " << SPI.getLine() - << " \"" << SPI.getDirectory() - << SPI.getFileName() << "\"\n"; + << " \""; + Out << SPIStr.str(); + SPIStr.clear(); + SPI.getFileName()->print(SPIStr); + Out << SPIStr.str() << "\"\n"; return true; } case Intrinsic::x86_sse_cmp_ss: @@ -2816,7 +3134,7 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, Out << ')'; // Multiple GCC builtins multiplex onto this intrinsic. switch (cast(I.getOperand(3))->getZExtValue()) { - default: assert(0 && "Invalid llvm.x86.sse.cmp!"); + default: llvm_unreachable("Invalid llvm.x86.sse.cmp!"); case 0: Out << "__builtin_ia32_cmpeq"; break; case 1: Out << "__builtin_ia32_cmplt"; break; case 2: Out << "__builtin_ia32_cmple"; break; @@ -2862,27 +3180,27 @@ std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) { const char *const *table = 0; - //Grab the translation table from TargetAsmInfo if it exists + // Grab the translation table from TargetAsmInfo if it exists. if (!TAsm) { std::string E; - const TargetMachineRegistry::entry* Match = - TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, E); + const Target *Match = + TargetRegistry::getClosestStaticTargetForModule(*TheModule, E); if (Match) { - //Per platform Target Machines don't exist, so create it - // this must be done only once - const TargetMachine* TM = Match->CtorFn(*TheModule, ""); + // Per platform Target Machines don't exist, so create it; + // this must be done only once. + const TargetMachine* TM = Match->createTargetMachine(*TheModule, ""); TAsm = TM->getTargetAsmInfo(); } } if (TAsm) table = TAsm->getAsmCBE(); - //Search the translation table if it exists + // Search the translation table if it exists. for (int i = 0; table && table[i]; i += 2) if (c.Codes[0] == table[i]) return table[i+1]; - //default is identity + // Default is identity. return c.Codes[0]; } @@ -2916,10 +3234,6 @@ static std::string gccifyAsm(std::string asmstr) { void CWriter::visitInlineAsm(CallInst &CI) { InlineAsm* as = cast(CI.getOperand(0)); std::vector Constraints = as->ParseConstraints(); - std::vector > Input; - std::vector > > Output; - std::string Clobber; - unsigned ValueCount = 0; std::vector > ResultVals; if (CI.getType() == Type::VoidTy) @@ -2931,66 +3245,108 @@ void CWriter::visitInlineAsm(CallInst &CI) { ResultVals.push_back(std::make_pair(&CI, -1)); } + // Fix up the asm string for gcc and emit it. + Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n"; + Out << " :"; + + unsigned ValueCount = 0; + bool IsFirst = true; + + // Convert over all the output constraints. for (std::vector::iterator I = Constraints.begin(), - E = Constraints.end(); I != E; ++I) { + E = Constraints.end(); I != E; ++I) { + + if (I->Type != InlineAsm::isOutput) { + ++ValueCount; + continue; // Ignore non-output constraints. + } + assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; - switch (I->Type) { - default: assert(0 && "Unknown asm constraint"); - case InlineAsm::isInput: { - assert(ValueCount >= ResultVals.size() && "Input can't refer to result"); - Value *V = CI.getOperand(ValueCount-ResultVals.size()+1); - Input.push_back(std::make_pair(C, V)); - break; - } - case InlineAsm::isOutput: { - std::pair V; - if (ValueCount < ResultVals.size()) - V = ResultVals[ValueCount]; - else - V = std::make_pair(CI.getOperand(ValueCount-ResultVals.size()+1), -1); - Output.push_back(std::make_pair("="+((I->isEarlyClobber ? "&" : "")+C), - V)); - break; - } - case InlineAsm::isClobber: - Clobber += ",\"" + C + "\""; - continue; // Not an actual argument. + if (!IsFirst) { + Out << ", "; + IsFirst = false; } - ++ValueCount; // Consumes an argument. + + // Unpack the dest. + Value *DestVal; + int DestValNo = -1; + + if (ValueCount < ResultVals.size()) { + DestVal = ResultVals[ValueCount].first; + DestValNo = ResultVals[ValueCount].second; + } else + DestVal = CI.getOperand(ValueCount-ResultVals.size()+1); + + if (I->isEarlyClobber) + C = "&"+C; + + Out << "\"=" << C << "\"(" << GetValueName(DestVal); + if (DestValNo != -1) + Out << ".field" << DestValNo; // Multiple retvals. + Out << ")"; + ++ValueCount; } - // Fix up the asm string for gcc. - std::string asmstr = gccifyAsm(as->getAsmString()); - Out << "__asm__ volatile (\"" << asmstr << "\"\n"; - Out << " :"; - for (unsigned i = 0, e = Output.size(); i != e; ++i) { - if (i) + // Convert over all the input constraints. + Out << "\n :"; + IsFirst = true; + ValueCount = 0; + for (std::vector::iterator I = Constraints.begin(), + E = Constraints.end(); I != E; ++I) { + if (I->Type != InlineAsm::isInput) { + ++ValueCount; + continue; // Ignore non-input constraints. + } + + assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); + std::string C = InterpretASMConstraint(*I); + if (C.empty()) continue; + + if (!IsFirst) { Out << ", "; - Out << "\"" << Output[i].first << "\"(" - << GetValueName(Output[i].second.first); - if (Output[i].second.second != -1) - Out << ".field" << Output[i].second.second; // Multiple retvals. + IsFirst = false; + } + + assert(ValueCount >= ResultVals.size() && "Input can't refer to result"); + Value *SrcVal = CI.getOperand(ValueCount-ResultVals.size()+1); + + Out << "\"" << C << "\"("; + if (!I->isIndirect) + writeOperand(SrcVal); + else + writeOperandDeref(SrcVal); Out << ")"; } - Out << "\n :"; - for (unsigned i = 0, e = Input.size(); i != e; ++i) { - if (i) + + // Convert over the clobber constraints. + IsFirst = true; + ValueCount = 0; + for (std::vector::iterator I = Constraints.begin(), + E = Constraints.end(); I != E; ++I) { + if (I->Type != InlineAsm::isClobber) + continue; // Ignore non-input constraints. + + assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); + std::string C = InterpretASMConstraint(*I); + if (C.empty()) continue; + + if (!IsFirst) { Out << ", "; - Out << "\"" << Input[i].first << "\"("; - writeOperand(Input[i].second); - Out << ")"; + IsFirst = false; + } + + Out << '\"' << C << '"'; } - if (Clobber.size()) - Out << "\n :" << Clobber.substr(1); + Out << ")"; } void CWriter::visitMallocInst(MallocInst &I) { - assert(0 && "lowerallocations pass didn't work!"); + llvm_unreachable("lowerallocations pass didn't work!"); } void CWriter::visitAllocaInst(AllocaInst &I) { @@ -3007,11 +3363,11 @@ void CWriter::visitAllocaInst(AllocaInst &I) { } void CWriter::visitFreeInst(FreeInst &I) { - assert(0 && "lowerallocations pass didn't work!"); + llvm_unreachable("lowerallocations pass didn't work!"); } void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I, - gep_type_iterator E) { + gep_type_iterator E, bool Static) { // If there are no indices, just print out the pointer. if (I == E) { @@ -3053,7 +3409,7 @@ void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I, // Okay, emit the first operand. If Ptr is something that is already address // exposed, like a global, avoid emitting (&foo)[0], just emit foo instead. if (isAddressExposed(Ptr)) { - writeOperandInternal(Ptr); + writeOperandInternal(Ptr, Static); } else if (I != E && isa(*I)) { // If we didn't already emit the first operand, see if we can print it as // P->f instead of "P[0].f" @@ -3071,6 +3427,10 @@ void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I, for (; I != E; ++I) { if (isa(*I)) { Out << ".field" << cast(I.getOperand())->getZExtValue(); + } else if (isa(*I)) { + Out << ".array["; + writeOperandWithCast(I.getOperand(), Instruction::GetElementPtr); + Out << ']'; } else if (!isa(*I)) { Out << '['; writeOperandWithCast(I.getOperand(), Instruction::GetElementPtr); @@ -3137,20 +3497,20 @@ void CWriter::visitStoreInst(StoreInst &I) { if (!ITy->isPowerOf2ByteWidth()) // We have a bit width that doesn't match an even power-of-2 byte // size. Consequently we must & the value with the type's bit mask - BitMask = ConstantInt::get(ITy, ITy->getBitMask()); + BitMask = Context->getConstantInt(ITy, ITy->getBitMask()); if (BitMask) Out << "(("; writeOperand(Operand); if (BitMask) { Out << ") & "; - printConstant(BitMask); + printConstant(BitMask, false); Out << ")"; } } void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { printGEPExpression(I.getPointerOperand(), gep_type_begin(I), - gep_type_end(I)); + gep_type_end(I), false); } void CWriter::visitVAArgInst(VAArgInst &I) { @@ -3205,25 +3565,56 @@ void CWriter::visitShuffleVectorInst(ShuffleVectorInst &SVI) { Out << "(("; printType(Out, PointerType::getUnqual(EltTy)); Out << ")(&" << GetValueName(Op) - << "))[" << (SrcVal & NumElts-1) << "]"; + << "))[" << (SrcVal & (NumElts-1)) << "]"; } else if (isa(Op) || isa(Op)) { Out << "0"; } else { - printConstant(cast(Op)->getOperand(SrcVal & NumElts-1)); + printConstant(cast(Op)->getOperand(SrcVal & + (NumElts-1)), + false); } } } Out << "}"; } -void CWriter::visitGetResultInst(GetResultInst &GRI) { +void CWriter::visitInsertValueInst(InsertValueInst &IVI) { + // Start by copying the entire aggregate value into the result variable. + writeOperand(IVI.getOperand(0)); + Out << ";\n "; + + // Then do the insert to update the field. + Out << GetValueName(&IVI); + for (const unsigned *b = IVI.idx_begin(), *i = b, *e = IVI.idx_end(); + i != e; ++i) { + const Type *IndexedTy = + ExtractValueInst::getIndexedType(IVI.getOperand(0)->getType(), b, i+1); + if (isa(IndexedTy)) + Out << ".array[" << *i << "]"; + else + Out << ".field" << *i; + } + Out << " = "; + writeOperand(IVI.getOperand(1)); +} + +void CWriter::visitExtractValueInst(ExtractValueInst &EVI) { Out << "("; - if (isa(GRI.getOperand(0))) { + if (isa(EVI.getOperand(0))) { Out << "("; - printType(Out, GRI.getType()); + printType(Out, EVI.getType()); Out << ") 0/*UNDEF*/"; } else { - Out << GetValueName(GRI.getOperand(0)) << ".field" << GRI.getIndex(); + Out << GetValueName(EVI.getOperand(0)); + for (const unsigned *b = EVI.idx_begin(), *i = b, *e = EVI.idx_end(); + i != e; ++i) { + const Type *IndexedTy = + ExtractValueInst::getIndexedType(EVI.getOperand(0)->getType(), b, i+1); + if (isa(IndexedTy)) + Out << ".array[" << *i << "]"; + else + Out << ".field" << *i; + } } Out << ")"; } @@ -3233,9 +3624,9 @@ void CWriter::visitGetResultInst(GetResultInst &GRI) { //===----------------------------------------------------------------------===// bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM, - std::ostream &o, + formatted_raw_ostream &o, CodeGenFileType FileType, - bool Fast) { + CodeGenOpt::Level OptLevel) { if (FileType != TargetMachine::AssemblyFile) return true; PM.add(createGCLoweringPass()); @@ -3244,6 +3635,6 @@ bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM, PM.add(createCFGSimplificationPass()); // clean up after lower invoke. PM.add(new CBackendNameAllUsedStructsAndMergeFunctions()); PM.add(new CWriter(o)); - PM.add(createCollectorMetadataDeleter()); + PM.add(createGCInfoDeleter()); return false; }