diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 37 | ||||
-rw-r--r-- | lib/CodeGen/CGCXXTemp.cpp | 67 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 26 | ||||
-rw-r--r-- | lib/Driver/HostInfo.cpp | 29 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/Backend.cpp | 114 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 10 |
9 files changed, 155 insertions, 148 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3b40526..b36d1f3 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -828,6 +828,13 @@ QualType ASTContext::getObjCGCQualType(QualType T, if (CanT.getObjCGCAttr() == GCAttr) return T; + if (T->isPointerType()) { + QualType Pointee = T->getAsPointerType()->getPointeeType(); + if (Pointee->isPointerType()) { + QualType ResultType = getObjCGCQualType(Pointee, GCAttr); + return getPointerType(ResultType); + } + } // If we are composing extended qualifiers together, merge together into one // ExtQualType node. unsigned CVRQuals = T.getCVRQualifiers(); diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 731e38c..4f9a4ca 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -189,43 +189,6 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, E->arg_begin(), E->arg_end()); } -void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, - llvm::Value *Ptr) { - LiveTemporaries.push_back(Temporary); - - // Make a cleanup scope and emit the destructor. - { - CleanupScope Scope(*this); - - EmitCXXDestructorCall(Temporary->getDestructor(), Dtor_Complete, Ptr); - } -} - -RValue -CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E, - llvm::Value *AggLoc, - bool isAggLocVolatile) { - // Keep track of the current cleanup stack depth. - size_t CleanupStackDepth = CleanupEntries.size(); - - unsigned OldNumLiveTemporaries = LiveTemporaries.size(); - - RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile); - - // Go through the temporaries backwards. - for (unsigned i = E->getNumTemporaries(); i != 0; --i) { - assert(LiveTemporaries.back() == E->getTemporary(i - 1)); - LiveTemporaries.pop_back(); - } - - assert(OldNumLiveTemporaries == LiveTemporaries.size() && - "Live temporary stack mismatch!"); - - EmitCleanupBlocks(CleanupStackDepth); - - return RV; -} - llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { if (E->isArray()) { ErrorUnsupported(E, "new[] expression"); diff --git a/lib/CodeGen/CGCXXTemp.cpp b/lib/CodeGen/CGCXXTemp.cpp new file mode 100644 index 0000000..d53a56f --- /dev/null +++ b/lib/CodeGen/CGCXXTemp.cpp @@ -0,0 +1,67 @@ +//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This contains code dealing with C++ code generation of temporaries +// +//===----------------------------------------------------------------------===// + +#include "CodeGenFunction.h" +using namespace clang; +using namespace CodeGen; + +void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, + llvm::Value *Ptr) { + llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor"); + + LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock, 0)); +} + +void CodeGenFunction::PopCXXTemporary() { + const CXXLiveTemporaryInfo& Info = LiveTemporaries.back(); + + CleanupBlockInfo CleanupInfo = PopCleanupBlock(); + assert(CleanupInfo.CleanupBlock == Info.DtorBlock && + "Cleanup block mismatch!"); + assert(!CleanupInfo.SwitchBlock && + "Should not have a switch block for temporary cleanup!"); + assert(!CleanupInfo.EndBlock && + "Should not have an end block for temporary cleanup!"); + + EmitBlock(Info.DtorBlock); + + EmitCXXDestructorCall(Info.Temporary->getDestructor(), + Dtor_Complete, Info.ThisPtr); + + LiveTemporaries.pop_back(); +} + +RValue +CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E, + llvm::Value *AggLoc, + bool isAggLocVolatile) { + // Keep track of the current cleanup stack depth. + size_t CleanupStackDepth = CleanupEntries.size(); + + unsigned OldNumLiveTemporaries = LiveTemporaries.size(); + + RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile); + + // Go through the temporaries backwards. + for (unsigned i = E->getNumTemporaries(); i != 0; --i) { + assert(LiveTemporaries.back().Temporary == E->getTemporary(i - 1)); + LiveTemporaries.pop_back(); + } + + assert(OldNumLiveTemporaries == LiveTemporaries.size() && + "Live temporary stack mismatch!"); + + EmitCleanupBlocks(CleanupStackDepth); + + return RV; +} diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 469c830..8d903d9 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -166,12 +166,12 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { void AggExprEmitter::VisitCStyleCastExpr(CStyleCastExpr *E) { // GCC union extension - if (E->getType()->isUnionType()) { - RecordDecl *SD = E->getType()->getAsRecordType()->getDecl(); - LValue FieldLoc = CGF.EmitLValueForField(DestPtr, - *SD->field_begin(CGF.getContext()), - true, 0); - EmitInitializationToLValue(E->getSubExpr(), FieldLoc); + if (E->getSubExpr()->getType()->isScalarType()) { + QualType PtrTy = + CGF.getContext().getPointerType(E->getSubExpr()->getType()); + llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr, + CGF.ConvertType(PtrTy)); + EmitInitializationToLValue(E->getSubExpr(), LValue::MakeAddr(CastPtr, 0)); return; } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index b7894a4..c91a052 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -239,7 +239,30 @@ private: /// 'this' declaration. ImplicitParamDecl *CXXThisDecl; - llvm::SmallVector<const CXXTemporary*, 4> LiveTemporaries; + /// CXXLiveTemporaryInfo - Holds information about a live C++ temporary. + struct CXXLiveTemporaryInfo { + /// Temporary - The live temporary. + const CXXTemporary *Temporary; + + /// ThisPtr - The pointer to the temporary. + llvm::Value *ThisPtr; + + /// DtorBlock - The destructor block. + llvm::BasicBlock *DtorBlock; + + /// CondPtr - If this is a conditional temporary, this is the pointer to + /// the condition variable that states whether the destructor should be + /// called or not. + llvm::Value *CondPtr; + + CXXLiveTemporaryInfo(const CXXTemporary *temporary, + llvm::Value *thisptr, llvm::BasicBlock *dtorblock, + llvm::Value *condptr) + : Temporary(temporary), ThisPtr(thisptr), DtorBlock(dtorblock), + CondPtr(condptr) { } + }; + + llvm::SmallVector<CXXLiveTemporaryInfo, 4> LiveTemporaries; public: CodeGenFunction(CodeGenModule &cgm); @@ -483,6 +506,7 @@ public: llvm::Value *This); void PushCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr); + void PopCXXTemporary(); llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E); diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp index 603b3ab..2d577f8 100644 --- a/lib/Driver/HostInfo.cpp +++ b/lib/Driver/HostInfo.cpp @@ -194,11 +194,13 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args, std::string Arch = getArchName(); ArchName = Arch.c_str(); if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { - if (getArchName() == "i386" || getArchName() == "x86_64") { - ArchName = + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64"; - } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") { - ArchName = + } else if (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64) { + ArchName = (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64"; } } @@ -361,13 +363,26 @@ ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args, assert(!ArchName && "Unexpected arch name on platform without driver driver support."); - ArchName = getArchName().c_str(); - + // Automatically handle some instances of -m32/-m64 we know about. + std::string Arch = getArchName(); + ArchName = Arch.c_str(); + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64"; + } else if (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64) { + ArchName = + (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64"; + } + } + ToolChain *&TC = ToolChains[ArchName]; if (!TC) { llvm::Triple TCTriple(getTriple()); - TCTriple.setArchName(getArchName()); + TCTriple.setArchName(ArchName); TC = new toolchains::Linux(*this, TCTriple); } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index abfabbb..eca6413 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -562,6 +562,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_dD); Args.AddAllArgValues(CmdArgs, options::OPT_Xclang); + Args.AddAllArgValues(CmdArgs, options::OPT_mllvm); if (Output.getType() == types::TY_Dependencies) { // Handled with other dependency code. diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp index 697ba94..9560b61 100644 --- a/lib/Frontend/Backend.cpp +++ b/lib/Frontend/Backend.cpp @@ -26,6 +26,7 @@ #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/StandardPasses.h" #include "llvm/Support/Timer.h" #include "llvm/System/Path.h" #include "llvm/System/Program.h" @@ -33,8 +34,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachineRegistry.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/IPO.h" using namespace clang; using namespace llvm; @@ -265,99 +264,31 @@ void BackendConsumer::CreatePasses() { if (CompileOpts.VerifyModule) getPerFunctionPasses()->add(createVerifierPass()); - if (CompileOpts.OptimizationLevel > 0) { - FunctionPassManager *PM = getPerFunctionPasses(); - PM->add(createCFGSimplificationPass()); - if (CompileOpts.OptimizationLevel == 1) - PM->add(createPromoteMemoryToRegisterPass()); - else - PM->add(createScalarReplAggregatesPass()); - PM->add(createInstructionCombiningPass()); + // Assume that standard function passes aren't run for -O0. + if (CompileOpts.OptimizationLevel > 0) + llvm::createStandardFunctionPasses(getPerFunctionPasses(), + CompileOpts.OptimizationLevel); + + llvm::Pass *InliningPass = 0; + switch (CompileOpts.Inlining) { + case CompileOptions::NoInlining: break; + case CompileOptions::NormalInlining: + InliningPass = createFunctionInliningPass(); // Inline small functions + break; + case CompileOptions::OnlyAlwaysInlining: + InliningPass = createAlwaysInlinerPass(); // Respect always_inline + break; } // For now we always create per module passes. PassManager *PM = getPerModulePasses(); - if (CompileOpts.OptimizationLevel > 0) { - if (CompileOpts.UnitAtATime) - PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst - PM->add(createCFGSimplificationPass()); // Clean up disgusting code - PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas - if (CompileOpts.UnitAtATime) { - PM->add(createGlobalOptimizerPass()); // Optimize out global vars - PM->add(createGlobalDCEPass()); // Remove unused fns and globs - PM->add(createIPConstantPropagationPass()); // IP Constant Propagation - PM->add(createDeadArgEliminationPass()); // Dead argument elimination - } - PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - if (CompileOpts.UnitAtATime) { - PM->add(createPruneEHPass()); // Remove dead EH info - PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs - } - switch (CompileOpts.Inlining) { - case CompileOptions::NoInlining: - break; - case CompileOptions::NormalInlining: - PM->add(createFunctionInliningPass()); // Inline small functions - break; - case CompileOptions::OnlyAlwaysInlining: - PM->add(createAlwaysInlinerPass()); // Respect always_inline - break; - } - if (CompileOpts.OptimizationLevel > 2) - PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args - if (CompileOpts.SimplifyLibCalls) - PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. - PM->add(createJumpThreadingPass()); // Thread jumps. - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas - PM->add(createInstructionCombiningPass()); // Combine silly seq's - PM->add(createCondPropagationPass()); // Propagate conditionals - PM->add(createTailCallEliminationPass()); // Eliminate tail calls - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createReassociatePass()); // Reassociate expressions - PM->add(createLoopRotatePass()); // Rotate Loop - PM->add(createLICMPass()); // Hoist loop invariants - PM->add(createLoopUnswitchPass(CompileOpts.OptimizeSize ? true : false)); -// PM->add(createLoopIndexSplitPass()); // Split loop index - PM->add(createInstructionCombiningPass()); - PM->add(createIndVarSimplifyPass()); // Canonicalize indvars - PM->add(createLoopDeletionPass()); // Delete dead loops - if (CompileOpts.UnrollLoops) - PM->add(createLoopUnrollPass()); // Unroll small loops - PM->add(createInstructionCombiningPass()); // Clean up after the unroller - PM->add(createGVNPass()); // Remove redundancies - PM->add(createMemCpyOptPass()); // Remove memcpy / form memset - PM->add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM->add(createInstructionCombiningPass()); - PM->add(createCondPropagationPass()); // Propagate conditionals - PM->add(createDeadStoreEliminationPass()); // Delete dead stores - PM->add(createAggressiveDCEPass()); // Delete dead instructions - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - - if (CompileOpts.UnitAtATime) { - PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - PM->add(createDeadTypeEliminationPass()); // Eliminate dead types - } - - if (CompileOpts.OptimizationLevel > 1 && CompileOpts.UnitAtATime) - PM->add(createConstantMergePass()); // Merge dup global constants - } else { - switch (CompileOpts.Inlining) { - case CompileOptions::NoInlining: - break; - case CompileOptions::NormalInlining: - PM->add(createFunctionInliningPass()); // Inline small functions - break; - case CompileOptions::OnlyAlwaysInlining: - PM->add(createAlwaysInlinerPass()); // Respect always_inline - break; - } - } + llvm::createStandardModulePasses(PM, CompileOpts.OptimizationLevel, + CompileOpts.OptimizeSize, + CompileOpts.UnitAtATime, + CompileOpts.UnrollLoops, + CompileOpts.SimplifyLibCalls, + /*HaveExceptions=*/true, + InliningPass); } /// EmitAssembly - Handle interaction with LLVM backend to generate @@ -367,7 +298,6 @@ void BackendConsumer::EmitAssembly() { if (!TheModule || !TheTargetData) return; - TimeRegion Region(CompileOpts.TimePasses ? &CodeGenerationTime : 0); // Make sure IR generation is happy with the module. This is diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 0945037..e3a45d4 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -129,15 +129,15 @@ template <typename T> static T PickFP(const llvm::fltSemantics *Sem, T IEEESingleVal, T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal, T IEEEQuadVal) { - if (Sem == &llvm::APFloat::IEEEsingle) + if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle) return IEEESingleVal; - if (Sem == &llvm::APFloat::IEEEdouble) + if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEdouble) return IEEEDoubleVal; - if (Sem == &llvm::APFloat::x87DoubleExtended) + if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::x87DoubleExtended) return X87DoubleExtendedVal; - if (Sem == &llvm::APFloat::PPCDoubleDouble) + if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble) return PPCDoubleDoubleVal; - assert(Sem == &llvm::APFloat::IEEEquad); + assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad); return IEEEQuadVal; } |