mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
Implement test/Regression/Transforms/GlobalConstifier/phi-select.llx
This allows more globals to be marked constant, particularly global arrays. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15735 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9a8e008751
commit
77a2a9d9da
@ -25,6 +25,7 @@
|
|||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "Support/Debug.h"
|
#include "Support/Debug.h"
|
||||||
#include "Support/Statistic.h"
|
#include "Support/Statistic.h"
|
||||||
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -52,16 +53,23 @@ static bool ContainingFunctionIsTriviallyDead(Instruction *I) {
|
|||||||
/// isStoredThrough - Return false if the specified pointer is provably never
|
/// isStoredThrough - Return false if the specified pointer is provably never
|
||||||
/// stored through. If we can't tell, we must conservatively assume it might.
|
/// stored through. If we can't tell, we must conservatively assume it might.
|
||||||
///
|
///
|
||||||
static bool isStoredThrough(Value *V) {
|
static bool isStoredThrough(Value *V, std::set<PHINode*> &PHIUsers) {
|
||||||
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
|
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
|
||||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
|
||||||
if (isStoredThrough(CE))
|
if (isStoredThrough(CE, PHIUsers))
|
||||||
return true;
|
return true;
|
||||||
} else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
|
} else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
|
||||||
if (!ContainingFunctionIsTriviallyDead(I)) {
|
if (!ContainingFunctionIsTriviallyDead(I)) {
|
||||||
if (I->getOpcode() == Instruction::GetElementPtr) {
|
if (I->getOpcode() == Instruction::GetElementPtr ||
|
||||||
if (isStoredThrough(I)) return true;
|
I->getOpcode() == Instruction::Select) {
|
||||||
} else if (!isa<LoadInst>(*UI) && !isa<SetCondInst>(*UI)) {
|
if (isStoredThrough(I, PHIUsers)) return true;
|
||||||
|
} else if (PHINode *PN = dyn_cast<PHINode>(I)) {
|
||||||
|
// PHI nodes we can check just like select or GEP instructions, but we
|
||||||
|
// have to be careful about infinite recursion.
|
||||||
|
if (PHIUsers.insert(PN).second) // Not already visited.
|
||||||
|
if (isStoredThrough(I, PHIUsers)) return true;
|
||||||
|
|
||||||
|
} else if (!isa<LoadInst>(I) && !isa<SetCondInst>(I)) {
|
||||||
return true; // Any other non-load instruction might store!
|
return true; // Any other non-load instruction might store!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,14 +83,16 @@ static bool isStoredThrough(Value *V) {
|
|||||||
|
|
||||||
bool Constifier::run(Module &M) {
|
bool Constifier::run(Module &M) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
std::set<PHINode*> PHIUsers;
|
||||||
for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
|
for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
|
||||||
if (!GV->isConstant() && GV->hasInternalLinkage() && GV->hasInitializer()) {
|
if (!GV->isConstant() && GV->hasInternalLinkage() && GV->hasInitializer()) {
|
||||||
if (!isStoredThrough(GV)) {
|
if (!isStoredThrough(GV, PHIUsers)) {
|
||||||
DEBUG(std::cerr << "MARKING CONSTANT: " << *GV << "\n");
|
DEBUG(std::cerr << "MARKING CONSTANT: " << *GV << "\n");
|
||||||
GV->setConstant(true);
|
GV->setConstant(true);
|
||||||
++NumMarked;
|
++NumMarked;
|
||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
PHIUsers.clear();
|
||||||
}
|
}
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user