mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-15 23:31:37 +00:00
Enhance DSE to handle the case where a free call makes more than
one store dead. This is especially noticeable in SingleSource/Benchmarks/Shootout/objinst. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118875 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
02df7e90cf
commit
720a2ed6d9
@ -59,6 +59,7 @@ namespace {
|
||||
|
||||
bool runOnBasicBlock(BasicBlock &BB);
|
||||
bool handleFreeWithNonTrivialDependency(const CallInst *F,
|
||||
Instruction *Inst,
|
||||
MemDepResult Dep);
|
||||
bool handleEndBlock(BasicBlock &BB);
|
||||
bool RemoveUndeadPointers(Value *Ptr, uint64_t killPointerSize,
|
||||
@ -212,7 +213,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
|
||||
|
||||
// Handle frees whose dependencies are non-trivial.
|
||||
if (const CallInst *F = isFreeCall(Inst)) {
|
||||
MadeChange |= handleFreeWithNonTrivialDependency(F, InstDep);
|
||||
MadeChange |= handleFreeWithNonTrivialDependency(F, Inst, InstDep);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -298,23 +299,34 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
|
||||
/// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose
|
||||
/// dependency is a store to a field of that structure.
|
||||
bool DSE::handleFreeWithNonTrivialDependency(const CallInst *F,
|
||||
Instruction *Inst,
|
||||
MemDepResult Dep) {
|
||||
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
||||
MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
|
||||
|
||||
Instruction *Dependency = Dep.getInst();
|
||||
if (!Dependency || !doesClobberMemory(Dependency) || !isElidable(Dependency))
|
||||
return false;
|
||||
do {
|
||||
Instruction *Dependency = Dep.getInst();
|
||||
if (!Dependency || !doesClobberMemory(Dependency) || !isElidable(Dependency))
|
||||
return false;
|
||||
|
||||
Value *DepPointer = getPointerOperand(Dependency)->getUnderlyingObject();
|
||||
Value *DepPointer = getPointerOperand(Dependency)->getUnderlyingObject();
|
||||
|
||||
// Check for aliasing.
|
||||
if (AA.alias(F->getArgOperand(0), 1, DepPointer, 1) !=
|
||||
AliasAnalysis::MustAlias)
|
||||
return false;
|
||||
// Check for aliasing.
|
||||
if (AA.alias(F->getArgOperand(0), 1, DepPointer, 1) !=
|
||||
AliasAnalysis::MustAlias)
|
||||
return false;
|
||||
|
||||
// DCE instructions only used to calculate that store
|
||||
DeleteDeadInstruction(Dependency);
|
||||
++NumFastStores;
|
||||
// DCE instructions only used to calculate that store
|
||||
DeleteDeadInstruction(Dependency);
|
||||
++NumFastStores;
|
||||
|
||||
// Inst's old Dependency is now deleted. Compute the next dependency,
|
||||
// which may also be dead, as in
|
||||
// s[0] = 0;
|
||||
// s[1] = 0; // This has just been deleted.
|
||||
// free(s);
|
||||
Dep = MD.getDependency(Inst);
|
||||
} while (!Dep.isNonLocal());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -24,3 +24,17 @@ define void @test2({i32, i32}* %P) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: @test4
|
||||
; CHECK-NOT: store
|
||||
; CHECK: ret void
|
||||
define void @test4() {
|
||||
%m = call i8* @malloc(i64 24)
|
||||
store i8 0, i8* %m
|
||||
%m1 = getelementptr i8* %m, i64 1
|
||||
store i8 1, i8* %m1
|
||||
call void @free(i8* %m)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @free(i8*)
|
||||
declare i8* @malloc(i64)
|
||||
|
Loading…
x
Reference in New Issue
Block a user