mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
revert r8579[56], which are causing unhappiness in buildbot land.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85818 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d442ab87b3
commit
3774c91854
@ -99,6 +99,7 @@ namespace llvm {
|
|||||||
if (UnitAtATime) {
|
if (UnitAtATime) {
|
||||||
PM->add(createGlobalOptimizerPass()); // Optimize out global vars
|
PM->add(createGlobalOptimizerPass()); // Optimize out global vars
|
||||||
|
|
||||||
|
PM->add(createIPConstantPropagationPass()); // IP CP
|
||||||
PM->add(createIPSCCPPass()); // IP SCCP
|
PM->add(createIPSCCPPass()); // IP SCCP
|
||||||
PM->add(createDeadArgEliminationPass()); // Dead argument elimination
|
PM->add(createDeadArgEliminationPass()); // Dead argument elimination
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Analysis/ConstantFolding.h"
|
#include "llvm/Analysis/ConstantFolding.h"
|
||||||
|
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
@ -226,6 +227,7 @@ public:
|
|||||||
/// and out of the specified function (which cannot have its address taken),
|
/// and out of the specified function (which cannot have its address taken),
|
||||||
/// this method must be called.
|
/// this method must be called.
|
||||||
void AddTrackedFunction(Function *F) {
|
void AddTrackedFunction(Function *F) {
|
||||||
|
assert(F->hasLocalLinkage() && "Can only track internal functions!");
|
||||||
// Add an entry, F -> undef.
|
// Add an entry, F -> undef.
|
||||||
if (const StructType *STy = dyn_cast<StructType>(F->getReturnType())) {
|
if (const StructType *STy = dyn_cast<StructType>(F->getReturnType())) {
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
||||||
@ -378,9 +380,11 @@ private:
|
|||||||
// instruction that was just changed state somehow. Based on this
|
// instruction that was just changed state somehow. Based on this
|
||||||
// information, we need to update the specified user of this instruction.
|
// information, we need to update the specified user of this instruction.
|
||||||
//
|
//
|
||||||
void OperandChangedState(Instruction *I) {
|
void OperandChangedState(User *U) {
|
||||||
if (BBExecutable.count(I->getParent())) // Inst is executable?
|
// Only instructions use other variable values!
|
||||||
visit(*I);
|
Instruction &I = cast<Instruction>(*U);
|
||||||
|
if (BBExecutable.count(I.getParent())) // Inst is executable?
|
||||||
|
visit(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RemoveFromOverdefinedPHIs - If I has any entries in the
|
/// RemoveFromOverdefinedPHIs - If I has any entries in the
|
||||||
@ -424,6 +428,8 @@ private:
|
|||||||
void visitLoadInst (LoadInst &I);
|
void visitLoadInst (LoadInst &I);
|
||||||
void visitGetElementPtrInst(GetElementPtrInst &I);
|
void visitGetElementPtrInst(GetElementPtrInst &I);
|
||||||
void visitCallInst (CallInst &I) {
|
void visitCallInst (CallInst &I) {
|
||||||
|
if (isFreeCall(&I))
|
||||||
|
return;
|
||||||
visitCallSite(CallSite::get(&I));
|
visitCallSite(CallSite::get(&I));
|
||||||
}
|
}
|
||||||
void visitInvokeInst (InvokeInst &II) {
|
void visitInvokeInst (InvokeInst &II) {
|
||||||
@ -650,19 +656,19 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
|
|||||||
markConstant(&PN, OperandVal); // Acquire operand value
|
markConstant(&PN, OperandVal); // Acquire operand value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SCCPSolver::visitReturnInst(ReturnInst &I) {
|
void SCCPSolver::visitReturnInst(ReturnInst &I) {
|
||||||
if (I.getNumOperands() == 0) return; // ret void
|
if (I.getNumOperands() == 0) return; // ret void
|
||||||
|
|
||||||
Function *F = I.getParent()->getParent();
|
Function *F = I.getParent()->getParent();
|
||||||
|
|
||||||
// If we are tracking the return value of this function, merge it in.
|
// If we are tracking the return value of this function, merge it in.
|
||||||
|
if (!F->hasLocalLinkage())
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TrackedRetVals.empty()) {
|
if (!TrackedRetVals.empty()) {
|
||||||
DenseMap<Function*, LatticeVal>::iterator TFRVI =
|
DenseMap<Function*, LatticeVal>::iterator TFRVI =
|
||||||
TrackedRetVals.find(F);
|
TrackedRetVals.find(F);
|
||||||
if (TFRVI != TrackedRetVals.end()) {
|
if (TFRVI != TrackedRetVals.end() &&
|
||||||
|
!TFRVI->second.isOverdefined()) {
|
||||||
mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0)));
|
mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1158,14 +1164,14 @@ void SCCPSolver::visitCallSite(CallSite CS) {
|
|||||||
// The common case is that we aren't tracking the callee, either because we
|
// The common case is that we aren't tracking the callee, either because we
|
||||||
// are not doing interprocedural analysis or the callee is indirect, or is
|
// are not doing interprocedural analysis or the callee is indirect, or is
|
||||||
// external. Handle these cases first.
|
// external. Handle these cases first.
|
||||||
if (F == 0 || F->isDeclaration()) {
|
if (F == 0 || !F->hasLocalLinkage()) {
|
||||||
CallOverdefined:
|
CallOverdefined:
|
||||||
// Void return and not tracking callee, just bail.
|
// Void return and not tracking callee, just bail.
|
||||||
if (I->getType()->isVoidTy()) return;
|
if (I->getType()->isVoidTy()) return;
|
||||||
|
|
||||||
// Otherwise, if we have a single return value case, and if the function is
|
// Otherwise, if we have a single return value case, and if the function is
|
||||||
// a declaration, maybe we can constant fold it.
|
// a declaration, maybe we can constant fold it.
|
||||||
if (F && F->isDeclaration() && !isa<StructType>(I->getType()) &&
|
if (!isa<StructType>(I->getType()) && F && F->isDeclaration() &&
|
||||||
canConstantFoldCallTo(F)) {
|
canConstantFoldCallTo(F)) {
|
||||||
|
|
||||||
SmallVector<Constant*, 8> Operands;
|
SmallVector<Constant*, 8> Operands;
|
||||||
@ -1229,7 +1235,7 @@ CallOverdefined:
|
|||||||
// common path above.
|
// common path above.
|
||||||
goto CallOverdefined;
|
goto CallOverdefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, if this is the first call to the function hit, mark its entry
|
// Finally, if this is the first call to the function hit, mark its entry
|
||||||
// block executable.
|
// block executable.
|
||||||
MarkBlockExecutable(F->begin());
|
MarkBlockExecutable(F->begin());
|
||||||
@ -1238,8 +1244,6 @@ CallOverdefined:
|
|||||||
CallSite::arg_iterator CAI = CS.arg_begin();
|
CallSite::arg_iterator CAI = CS.arg_begin();
|
||||||
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
|
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
|
||||||
AI != E; ++AI, ++CAI) {
|
AI != E; ++AI, ++CAI) {
|
||||||
// If this argument is byval, and if the function is not readonly, there
|
|
||||||
// will be an implicit copy formed of the input aggregate.
|
|
||||||
if (AI->hasByValAttr() && !F->onlyReadsMemory()) {
|
if (AI->hasByValAttr() && !F->onlyReadsMemory()) {
|
||||||
markOverdefined(AI);
|
markOverdefined(AI);
|
||||||
continue;
|
continue;
|
||||||
@ -1269,8 +1273,7 @@ void SCCPSolver::Solve() {
|
|||||||
//
|
//
|
||||||
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
||||||
UI != E; ++UI)
|
UI != E; ++UI)
|
||||||
if (Instruction *I = dyn_cast<Instruction>(*UI))
|
OperandChangedState(*UI);
|
||||||
OperandChangedState(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the instruction work list.
|
// Process the instruction work list.
|
||||||
@ -1289,8 +1292,7 @@ void SCCPSolver::Solve() {
|
|||||||
if (!getValueState(I).isOverdefined())
|
if (!getValueState(I).isOverdefined())
|
||||||
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
||||||
UI != E; ++UI)
|
UI != E; ++UI)
|
||||||
if (Instruction *I = dyn_cast<Instruction>(*UI))
|
OperandChangedState(*UI);
|
||||||
OperandChangedState(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the basic block work list.
|
// Process the basic block work list.
|
||||||
@ -1648,25 +1650,14 @@ bool IPSCCP::runOnModule(Module &M) {
|
|||||||
if (F->isDeclaration())
|
if (F->isDeclaration())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If this is a strong or ODR definition of this function, then we can
|
if (!F->hasLocalLinkage() || AddressIsTaken(F)) {
|
||||||
// propagate information about its result into callsites of it.
|
Solver.MarkBlockExecutable(F->begin());
|
||||||
if (!F->mayBeOverridden() &&
|
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
|
||||||
!isa<StructType>(F->getReturnType()))
|
AI != E; ++AI)
|
||||||
|
Solver.markOverdefined(AI);
|
||||||
|
} else {
|
||||||
Solver.AddTrackedFunction(F);
|
Solver.AddTrackedFunction(F);
|
||||||
|
}
|
||||||
// If this function only has direct calls that we can see, we can track its
|
|
||||||
// arguments and return value aggressively, and can assume it is not called
|
|
||||||
// unless we see evidence to the contrary.
|
|
||||||
if (F->hasLocalLinkage() && !AddressIsTaken(F))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Assume the function is called.
|
|
||||||
Solver.MarkBlockExecutable(F->begin());
|
|
||||||
|
|
||||||
// Assume nothing about the incoming arguments.
|
|
||||||
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
|
|
||||||
AI != E; ++AI)
|
|
||||||
Solver.markOverdefined(AI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop over global variables. We inform the solver about any internal global
|
// Loop over global variables. We inform the solver about any internal global
|
||||||
@ -1814,21 +1805,16 @@ bool IPSCCP::runOnModule(Module &M) {
|
|||||||
// TODO: Process multiple value ret instructions also.
|
// TODO: Process multiple value ret instructions also.
|
||||||
const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
|
const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
|
||||||
for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(),
|
for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(),
|
||||||
E = RV.end(); I != E; ++I) {
|
E = RV.end(); I != E; ++I)
|
||||||
Function *F = I->first;
|
if (!I->second.isOverdefined() &&
|
||||||
if (I->second.isOverdefined() || F->getReturnType()->isVoidTy())
|
!I->first->getReturnType()->isVoidTy()) {
|
||||||
continue;
|
Function *F = I->first;
|
||||||
|
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
||||||
// We can only do this if we know that nothing else can call the function.
|
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
|
||||||
if (!F->hasLocalLinkage() || AddressIsTaken(F))
|
if (!isa<UndefValue>(RI->getOperand(0)))
|
||||||
continue;
|
RI->setOperand(0, UndefValue::get(F->getReturnType()));
|
||||||
|
}
|
||||||
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
|
||||||
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
|
|
||||||
if (!isa<UndefValue>(RI->getOperand(0)))
|
|
||||||
RI->setOperand(0, UndefValue::get(F->getReturnType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we infered constant or undef values for globals variables, we can delete
|
// If we infered constant or undef values for globals variables, we can delete
|
||||||
// the global and any stores that remain to it.
|
// the global and any stores that remain to it.
|
||||||
const DenseMap<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals();
|
const DenseMap<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals();
|
||||||
|
Loading…
Reference in New Issue
Block a user