mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-21 02:24:22 +00:00
Implement FunctionResolve/2003-10-21-GlobalResolveHack.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9363 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -25,6 +25,7 @@
|
|||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "Support/Statistic.h"
|
#include "Support/Statistic.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -34,6 +35,10 @@ namespace {
|
|||||||
Statistic<> NumGlobals("funcresolve", "Number of global variables resolved");
|
Statistic<> NumGlobals("funcresolve", "Number of global variables resolved");
|
||||||
|
|
||||||
struct FunctionResolvingPass : public Pass {
|
struct FunctionResolvingPass : public Pass {
|
||||||
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.addRequired<TargetData>();
|
||||||
|
}
|
||||||
|
|
||||||
bool run(Module &M);
|
bool run(Module &M);
|
||||||
};
|
};
|
||||||
RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
|
RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
|
||||||
@ -125,7 +130,7 @@ static bool ResolveGlobalVariables(Module &M,
|
|||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ProcessGlobalsWithSameName(Module &M,
|
static bool ProcessGlobalsWithSameName(Module &M, TargetData &TD,
|
||||||
std::vector<GlobalValue*> &Globals) {
|
std::vector<GlobalValue*> &Globals) {
|
||||||
assert(!Globals.empty() && "Globals list shouldn't be empty here!");
|
assert(!Globals.empty() && "Globals list shouldn't be empty here!");
|
||||||
|
|
||||||
@ -202,6 +207,31 @@ static bool ProcessGlobalsWithSameName(Module &M,
|
|||||||
|
|
||||||
if (!Concrete)
|
if (!Concrete)
|
||||||
Concrete = Globals[0];
|
Concrete = Globals[0];
|
||||||
|
else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Concrete)) {
|
||||||
|
// Handle special case hack to change globals if it will make their types
|
||||||
|
// happier in the long run. The situation we do this is intentionally
|
||||||
|
// extremely limited.
|
||||||
|
if (GV->use_empty() && GV->hasInitializer() &&
|
||||||
|
GV->getInitializer()->isNullValue()) {
|
||||||
|
// Check to see if there is another (external) global with the same size
|
||||||
|
// and a non-empty use-list. If so, we will make IT be the real
|
||||||
|
// implementation.
|
||||||
|
unsigned TS = TD.getTypeSize(Concrete->getType()->getElementType());
|
||||||
|
for (unsigned i = 0, e = Globals.size(); i != e; ++i)
|
||||||
|
if (Globals[i] != Concrete && !Globals[i]->use_empty() &&
|
||||||
|
isa<GlobalVariable>(Globals[i]) &&
|
||||||
|
TD.getTypeSize(Globals[i]->getType()->getElementType()) == TS) {
|
||||||
|
// At this point we want to replace Concrete with Globals[i]. Make
|
||||||
|
// concrete external, and Globals[i] have an initializer.
|
||||||
|
GlobalVariable *NGV = cast<GlobalVariable>(Globals[i]);
|
||||||
|
const Type *ElTy = NGV->getType()->getElementType();
|
||||||
|
NGV->setInitializer(Constant::getNullValue(ElTy));
|
||||||
|
cast<GlobalVariable>(Concrete)->setInitializer(0);
|
||||||
|
Concrete = NGV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isFunction)
|
if (isFunction)
|
||||||
return ResolveFunctions(M, Globals, cast<Function>(Concrete));
|
return ResolveFunctions(M, Globals, cast<Function>(Concrete));
|
||||||
@ -236,12 +266,14 @@ bool FunctionResolvingPass::run(Module &M) {
|
|||||||
|
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
|
TargetData &TD = getAnalysis<TargetData>();
|
||||||
|
|
||||||
// Now we have a list of all functions with a particular name. If there is
|
// Now we have a list of all functions with a particular name. If there is
|
||||||
// more than one entry in a list, merge the functions together.
|
// more than one entry in a list, merge the functions together.
|
||||||
//
|
//
|
||||||
for (std::map<std::string, std::vector<GlobalValue*> >::iterator
|
for (std::map<std::string, std::vector<GlobalValue*> >::iterator
|
||||||
I = Globals.begin(), E = Globals.end(); I != E; ++I)
|
I = Globals.begin(), E = Globals.end(); I != E; ++I)
|
||||||
Changed |= ProcessGlobalsWithSameName(M, I->second);
|
Changed |= ProcessGlobalsWithSameName(M, TD, I->second);
|
||||||
|
|
||||||
// Now loop over all of the globals, checking to see if any are trivially
|
// Now loop over all of the globals, checking to see if any are trivially
|
||||||
// dead. If so, remove them now.
|
// dead. If so, remove them now.
|
||||||
|
Reference in New Issue
Block a user