forked from OSchip/llvm-project
parent
4162e3e213
commit
dcdfd8dd24
|
@ -39,7 +39,6 @@
|
||||||
#include "llvm/LLVMContext.h"
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Analysis/CallGraph.h"
|
#include "llvm/Analysis/CallGraph.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -440,8 +439,6 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const {
|
||||||
SmallPtrSet<BasicBlock*, 16> TranspBlocks;
|
SmallPtrSet<BasicBlock*, 16> TranspBlocks;
|
||||||
|
|
||||||
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
||||||
TargetData *TD = getAnalysisIfAvailable<TargetData>();
|
|
||||||
if (!TD) return false; // Without TargetData, assume the worst.
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = Loads.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Loads.size(); i != e; ++i) {
|
||||||
// Check to see if the load is invalidated from the start of the block to
|
// Check to see if the load is invalidated from the start of the block to
|
||||||
|
@ -449,11 +446,11 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const {
|
||||||
LoadInst *Load = Loads[i];
|
LoadInst *Load = Loads[i];
|
||||||
BasicBlock *BB = Load->getParent();
|
BasicBlock *BB = Load->getParent();
|
||||||
|
|
||||||
const PointerType *LoadTy =
|
AliasAnalysis::Location Loc(Load->getPointerOperand(),
|
||||||
cast<PointerType>(Load->getPointerOperand()->getType());
|
AA.getTypeStoreSize(Load->getType()),
|
||||||
uint64_t LoadSize = TD->getTypeStoreSize(LoadTy->getElementType());
|
Load->getMetadata(LLVMContext::MD_tbaa));
|
||||||
|
|
||||||
if (AA.canInstructionRangeModify(BB->front(), *Load, Arg, LoadSize))
|
if (AA.canInstructionRangeModify(BB->front(), *Load, Loc))
|
||||||
return false; // Pointer is invalidated!
|
return false; // Pointer is invalidated!
|
||||||
|
|
||||||
// Now check every path from the entry block to the load for transparency.
|
// Now check every path from the entry block to the load for transparency.
|
||||||
|
@ -464,7 +461,7 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const {
|
||||||
for (idf_ext_iterator<BasicBlock*, SmallPtrSet<BasicBlock*, 16> >
|
for (idf_ext_iterator<BasicBlock*, SmallPtrSet<BasicBlock*, 16> >
|
||||||
I = idf_ext_begin(P, TranspBlocks),
|
I = idf_ext_begin(P, TranspBlocks),
|
||||||
E = idf_ext_end(P, TranspBlocks); I != E; ++I)
|
E = idf_ext_end(P, TranspBlocks); I != E; ++I)
|
||||||
if (AA.canBasicBlockModify(**I, Arg, LoadSize))
|
if (AA.canBasicBlockModify(**I, Loc))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -700,6 +697,9 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
|
||||||
// of the previous load.
|
// of the previous load.
|
||||||
LoadInst *newLoad = new LoadInst(V, V->getName()+".val", Call);
|
LoadInst *newLoad = new LoadInst(V, V->getName()+".val", Call);
|
||||||
newLoad->setAlignment(OrigLoad->getAlignment());
|
newLoad->setAlignment(OrigLoad->getAlignment());
|
||||||
|
// Transfer the TBAA info too.
|
||||||
|
newLoad->setMetadata(LLVMContext::MD_tbaa,
|
||||||
|
OrigLoad->getMetadata(LLVMContext::MD_tbaa));
|
||||||
Args.push_back(newLoad);
|
Args.push_back(newLoad);
|
||||||
AA.copyValue(OrigLoad, Args.back());
|
AA.copyValue(OrigLoad, Args.back());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
; RUN: opt < %s -enable-tbaa -tbaa -basicaa -argpromotion -mem2reg -S | not grep alloca
|
||||||
|
|
||||||
|
target datalayout = "E-p:64:64:64"
|
||||||
|
|
||||||
|
define internal i32 @test(i32* %X, i32* %Y, i32* %Q) {
|
||||||
|
store i32 77, i32* %Q, !tbaa !2
|
||||||
|
%A = load i32* %X, !tbaa !1
|
||||||
|
%B = load i32* %Y, !tbaa !1
|
||||||
|
%C = add i32 %A, %B
|
||||||
|
ret i32 %C
|
||||||
|
}
|
||||||
|
|
||||||
|
define internal i32 @caller(i32* %B, i32* %Q) {
|
||||||
|
%A = alloca i32
|
||||||
|
store i32 78, i32* %Q, !tbaa !2
|
||||||
|
store i32 1, i32* %A, !tbaa !1
|
||||||
|
%C = call i32 @test(i32* %A, i32* %B, i32* %Q)
|
||||||
|
ret i32 %C
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @callercaller(i32* %Q) {
|
||||||
|
%B = alloca i32
|
||||||
|
store i32 2, i32* %B, !tbaa !1
|
||||||
|
store i32 79, i32* %Q, !tbaa !2
|
||||||
|
%X = call i32 @caller(i32* %B, i32* %Q)
|
||||||
|
ret i32 %X
|
||||||
|
}
|
||||||
|
|
||||||
|
!0 = metadata !{metadata !"test"}
|
||||||
|
!1 = metadata !{metadata !"green", metadata !0}
|
||||||
|
!2 = metadata !{metadata !"blue", metadata !0}
|
Loading…
Reference in New Issue