summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-04-11 23:51:38 +0000
committerNico Weber <nicolasweber@gmx.de>2015-04-11 23:51:38 +0000
commit1c565c31b161898d8ea32bd71c5ab55b5d6d2b83 (patch)
tree122eae39680aa0823699c05bf5d76fb24c4816ed /clang/lib/CodeGen
parent7ad0bd54d31788c4858cffa6e203cd06260b800b (diff)
downloadbcm5719-llvm-1c565c31b161898d8ea32bd71c5ab55b5d6d2b83.tar.gz
bcm5719-llvm-1c565c31b161898d8ea32bd71c5ab55b5d6d2b83.zip
Revert r234581, it might have caused a few miscompiles in Chromium.
If the revert helps, I'll get a repro this Monday. Else I'll put the change back in. llvm-svn: 234700
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp28
-rw-r--r--clang/lib/CodeGen/CGCleanup.cpp21
-rw-r--r--clang/lib/CodeGen/CGCleanup.h9
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp59
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
-rw-r--r--clang/lib/CodeGen/EHScopeStack.h4
7 files changed, 34 insertions, 100 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d82c58fb7e1..c031bd79409 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -30,7 +30,6 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Transforms/Utils/Local.h"
#include <sstream>
using namespace clang;
@@ -2217,29 +2216,7 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
if (!CGF.ReturnValue->hasOneUse()) {
llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
if (IP->empty()) return nullptr;
- llvm::Instruction *I = &IP->back();
-
- // Skip lifetime markers
- for (llvm::BasicBlock::reverse_iterator II = IP->rbegin(),
- IE = IP->rend();
- II != IE; ++II) {
- if (llvm::IntrinsicInst *Intrinsic =
- dyn_cast<llvm::IntrinsicInst>(&*II)) {
- if (Intrinsic->getIntrinsicID() == llvm::Intrinsic::lifetime_end) {
- const llvm::Value *CastAddr = Intrinsic->getArgOperand(1);
- ++II;
- if (isa<llvm::BitCastInst>(&*II)) {
- if (CastAddr == &*II) {
- continue;
- }
- }
- }
- }
- I = &*II;
- break;
- }
-
- llvm::StoreInst *store = dyn_cast<llvm::StoreInst>(I);
+ llvm::StoreInst *store = dyn_cast<llvm::StoreInst>(&IP->back());
if (!store) return nullptr;
if (store->getPointerOperand() != CGF.ReturnValue) return nullptr;
assert(!store->isAtomic() && !store->isVolatile()); // see below
@@ -2337,8 +2314,7 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
// If there is a dominating store to ReturnValue, we can elide
// the load, zap the store, and usually zap the alloca.
- if (llvm::StoreInst *SI =
- findDominatingStoreToReturnValue(*this)) {
+ if (llvm::StoreInst *SI = findDominatingStoreToReturnValue(*this)) {
// Reuse the debug location from the store unless there is
// cleanup code to be emitted between the store and return
// instruction.
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index d97e40554ef..299969a4649 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -125,17 +125,6 @@ char *EHScopeStack::allocate(size_t Size) {
return StartOfData;
}
-bool EHScopeStack::containsOnlyLifetimeMarkers(
- EHScopeStack::stable_iterator Old) const {
- for (EHScopeStack::iterator it = begin(); stabilize(it) != Old; it++) {
- EHCleanupScope *cleanup = dyn_cast<EHCleanupScope>(&*it);
- if (!cleanup || !cleanup->isLifetimeMarker())
- return false;
- }
-
- return true;
-}
-
EHScopeStack::stable_iterator
EHScopeStack::getInnermostActiveNormalCleanup() const {
for (stable_iterator si = getInnermostNormalCleanup(), se = stable_end();
@@ -759,15 +748,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
Scope.getNumBranchAfters() == 1) {
assert(!BranchThroughDest || !IsActive);
- // Clean up the possibly dead store to the cleanup dest slot.
- llvm::Instruction *NormalCleanupDestSlot =
- cast<llvm::Instruction>(getNormalCleanupDestSlot());
- if (NormalCleanupDestSlot->hasOneUse()) {
- NormalCleanupDestSlot->user_back()->eraseFromParent();
- NormalCleanupDestSlot->eraseFromParent();
- NormalCleanupDest = nullptr;
- }
-
+ // TODO: clean up the possibly dead stores to the cleanup dest slot.
llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);
InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));
diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h
index 81c64123dfd..5f94aec4978 100644
--- a/clang/lib/CodeGen/CGCleanup.h
+++ b/clang/lib/CodeGen/CGCleanup.h
@@ -62,9 +62,6 @@ protected:
/// Whether this cleanup is currently active.
unsigned IsActive : 1;
- /// Whether this cleanup is a lifetime marker
- unsigned IsLifetimeMarker : 1;
-
/// Whether the normal cleanup should test the activation flag.
unsigned TestFlagInNormalCleanup : 1;
@@ -78,7 +75,7 @@ protected:
/// The number of fixups required by enclosing scopes (not including
/// this one). If this is the top cleanup scope, all the fixups
/// from this index onwards belong to this scope.
- unsigned FixupDepth : 32 - 18 - NumCommonBits; // currently 13
+ unsigned FixupDepth : 32 - 17 - NumCommonBits; // currently 13
};
class FilterBitFields {
@@ -275,7 +272,6 @@ public:
CleanupBits.IsNormalCleanup = isNormal;
CleanupBits.IsEHCleanup = isEH;
CleanupBits.IsActive = isActive;
- CleanupBits.IsLifetimeMarker = false;
CleanupBits.TestFlagInNormalCleanup = false;
CleanupBits.TestFlagInEHCleanup = false;
CleanupBits.CleanupSize = cleanupSize;
@@ -299,9 +295,6 @@ public:
bool isActive() const { return CleanupBits.IsActive; }
void setActive(bool A) { CleanupBits.IsActive = A; }
- bool isLifetimeMarker() const { return CleanupBits.IsLifetimeMarker; }
- void setLifetimeMarker() { CleanupBits.IsLifetimeMarker = true; }
-
llvm::AllocaInst *getActiveFlag() const { return ActiveFlag; }
void setActiveFlag(llvm::AllocaInst *Var) { ActiveFlag = Var; }
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 29c63151466..f1ccb094f23 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
-#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGOpenCLRuntime.h"
#include "CodeGenModule.h"
@@ -517,7 +516,10 @@ namespace {
: Addr(addr), Size(size) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
- CGF.EmitLifetimeEnd(Size, Addr);
+ llvm::Value *castAddr = CGF.Builder.CreateBitCast(Addr, CGF.Int8PtrTy);
+ CGF.Builder.CreateCall2(CGF.CGM.getLLVMLifetimeEndFn(),
+ Size, castAddr)
+ ->setDoesNotThrow();
}
};
}
@@ -838,6 +840,21 @@ static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init,
canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);
}
+/// Should we use the LLVM lifetime intrinsics for the given local variable?
+static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
+ unsigned Size) {
+ // For now, only in optimized builds.
+ if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)
+ return false;
+
+ // Limit the size of marked objects to 32 bytes. We don't want to increase
+ // compile time by marking tiny objects.
+ unsigned SizeThreshold = 32;
+
+ return Size > SizeThreshold;
+}
+
+
/// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
/// variable declaration with auto, register, or no storage class specifier.
/// These turn into simple stack objects, or GlobalValues depending on target.
@@ -847,33 +864,6 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
EmitAutoVarCleanups(emission);
}
-/// Emit a lifetime.begin marker if some criteria are satisfied.
-/// \return a pointer to the temporary size Value if a marker was emitted, null
-/// otherwise
-llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
- llvm::Value *Addr) {
- // For now, only in optimized builds.
- if (CGM.getCodeGenOpts().OptimizationLevel == 0)
- return nullptr;
-
- llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
- llvm::Value *Args[] = {
- SizeV,
- new llvm::BitCastInst(Addr, Int8PtrTy, "", Builder.GetInsertBlock())};
- llvm::CallInst *C = llvm::CallInst::Create(CGM.getLLVMLifetimeStartFn(), Args,
- "", Builder.GetInsertBlock());
- C->setDoesNotThrow();
- return SizeV;
-}
-
-void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
- llvm::Value *Args[] = {Size, new llvm::BitCastInst(Addr, Int8PtrTy, "",
- Builder.GetInsertBlock())};
- llvm::CallInst *C = llvm::CallInst::Create(CGM.getLLVMLifetimeEndFn(), Args,
- "", Builder.GetInsertBlock());
- C->setDoesNotThrow();
-}
-
/// EmitAutoVarAlloca - Emit the alloca and debug information for a
/// local variable. Does not emit initialization or destruction.
CodeGenFunction::AutoVarEmission
@@ -969,8 +959,13 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// Emit a lifetime intrinsic if meaningful. There's no point
// in doing this if we don't have a valid insertion point (?).
uint64_t size = CGM.getDataLayout().getTypeAllocSize(LTy);
- if (HaveInsertPoint()) {
- emission.SizeForLifetimeMarkers = EmitLifetimeStart(size, Alloc);
+ if (HaveInsertPoint() && shouldUseLifetimeMarkers(*this, D, size)) {
+ llvm::Value *sizeV = llvm::ConstantInt::get(Int64Ty, size);
+
+ emission.SizeForLifetimeMarkers = sizeV;
+ llvm::Value *castAddr = Builder.CreateBitCast(Alloc, Int8PtrTy);
+ Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), sizeV, castAddr)
+ ->setDoesNotThrow();
} else {
assert(!emission.useLifetimeMarkers());
}
@@ -1316,8 +1311,6 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
EHStack.pushCleanup<CallLifetimeEnd>(NormalCleanup,
emission.getAllocatedAddress(),
emission.getSizeForLifetimeMarkers());
- EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin());
- cleanup.setLifetimeMarker();
}
// Check the type for a cleanup.
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 93f00113e9a..42c3a423fa0 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
-#include "CGCleanup.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGDebugInfo.h"
@@ -244,13 +243,12 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// parameters. Do this in whatever block we're currently in; it's
// important to do this before we enter the return block or return
// edges will be *really* confused.
- bool HasCleanups = EHStack.stable_begin() != PrologueCleanupDepth;
- bool HasOnlyLifetimeMarkers =
- HasCleanups && EHStack.containsOnlyLifetimeMarkers(PrologueCleanupDepth);
- bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
- if (HasCleanups) {
+ bool EmitRetDbgLoc = true;
+ if (EHStack.stable_begin() != PrologueCleanupDepth) {
// Make sure the line table doesn't jump back into the body for
// the ret after it's been at EndLoc.
+ EmitRetDbgLoc = false;
+
if (CGDebugInfo *DI = getDebugInfo())
if (OnlySimpleReturnStmts)
DI->EmitLocation(Builder, EndLoc);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 474bf57bb7b..343edc2ebf3 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1730,9 +1730,6 @@ public:
void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
llvm::Value *Ptr);
- llvm::Value *EmitLifetimeStart(uint64_t Size, llvm::Value *Addr);
- void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);
-
llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
diff --git a/clang/lib/CodeGen/EHScopeStack.h b/clang/lib/CodeGen/EHScopeStack.h
index a7951888c82..363d8b8fe4a 100644
--- a/clang/lib/CodeGen/EHScopeStack.h
+++ b/clang/lib/CodeGen/EHScopeStack.h
@@ -319,10 +319,6 @@ public:
/// Pops a terminate handler off the stack.
void popTerminate();
- // Returns true iff the current scope is either empty or contains only
- // lifetime markers, i.e. no real cleanup code
- bool containsOnlyLifetimeMarkers(stable_iterator Old) const;
-
/// Determines whether the exception-scopes stack is empty.
bool empty() const { return StartOfData == EndOfBuffer; }
OpenPOWER on IntegriCloud