summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp7
-rw-r--r--lib/CodeGen/CGCXX.cpp37
-rw-r--r--lib/CodeGen/CGCXXTemp.cpp67
-rw-r--r--lib/CodeGen/CGExprAgg.cpp12
-rw-r--r--lib/CodeGen/CodeGenFunction.h26
-rw-r--r--lib/Driver/HostInfo.cpp29
-rw-r--r--lib/Driver/Tools.cpp1
-rw-r--r--lib/Frontend/Backend.cpp114
-rw-r--r--lib/Frontend/InitPreprocessor.cpp10
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;
}
OpenPOWER on IntegriCloud