#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
-#include <set>
#include <algorithm>
+#include <iostream>
+#include <set>
using namespace llvm;
namespace {
bool OptimizeFunctions(Module &M);
bool OptimizeGlobalVars(Module &M);
bool OptimizeGlobalCtorsList(GlobalVariable *&GCL);
- bool ProcessInternalGlobal(GlobalVariable *GV, Module::global_iterator &GVI);
+ bool ProcessInternalGlobal(GlobalVariable *GV,Module::global_iterator &GVI);
};
- RegisterOpt<GlobalOpt> X("globalopt", "Global Variable Optimizer");
+ RegisterPass<GlobalOpt> X("globalopt", "Global Variable Optimizer");
}
ModulePass *llvm::createGlobalOptimizerPass() { return new GlobalOpt(); }
Constant *SubInit = 0;
ConstantExpr *CE =
dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP));
- if (CE && CE->getOpcode() == Instruction::GetElementPtr)
+ if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr)
SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
(unsigned)NElements->getRawValue());
MallocInst *NewMI =
new MallocInst(NewTy, Constant::getNullValue(Type::UIntTy),
- MI->getName(), MI);
+ MI->getAlignment(), MI->getName(), MI);
std::vector<Value*> Indices;
Indices.push_back(Constant::getNullValue(Type::IntTy));
Indices.push_back(Indices[0]);
// OptimizeOnceStoredGlobal - Try to optimize globals based on the knowledge
// that only one value (besides its initializer) is ever stored to the global.
static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
- Module::global_iterator &GVI, TargetData &TD) {
+ Module::global_iterator &GVI,
+ TargetData &TD) {
if (CastInst *CI = dyn_cast<CastInst>(StoredOnceVal))
StoredOnceVal = CI->getOperand(0);
else if (GetElementPtrInst *GEPI =dyn_cast<GetElementPtrInst>(StoredOnceVal)){
DEBUG(std::cerr << "LOCALIZING GLOBAL: " << *GV);
Instruction* FirstI = GS.AccessingFunction->getEntryBlock().begin();
const Type* ElemTy = GV->getType()->getElementType();
+ // FIXME: Pass Global's alignment when globals have alignment
AllocaInst* Alloca = new AllocaInst(ElemTy, NULL, GV->getName(), FirstI);
if (!isa<UndefValue>(GV->getInitializer()))
new StoreInst(GV->getInitializer(), Alloca, FirstI);
/// FindGlobalCtors - Find the llvm.globalctors list, verifying that all
/// initializers have an init priority of 65535.
GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
- for (Module::giterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
if (I->getName() == "llvm.global_ctors") {
// Found it, verify it's an array of { int, void()* }.
const ArrayType *ATy =dyn_cast<ArrayType>(I->getType()->getElementType());
/// we punt. We basically just support direct accesses to globals and GEP's of
/// globals. This should be kept up to date with CommitValueTo.
static bool isSimpleEnoughPointerToCommit(Constant *C) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
+ if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
+ return false; // do not allow weak/linkonce/dllimport/dllexport linkage.
return !GV->isExternal(); // reject external globals.
+ }
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
// Handle a constantexpr gep.
if (CE->getOpcode() == Instruction::GetElementPtr &&
isa<GlobalVariable>(CE->getOperand(0))) {
GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
+ if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
+ return false; // do not allow weak/linkonce/dllimport/dllexport linkage.
return GV->hasInitializer() &&
ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE);
}
AI->getName()));
InstResult = AllocaTmps.back();
} else if (CallInst *CI = dyn_cast<CallInst>(CurInst)) {
+ // Cannot handle inline asm.
+ if (isa<InlineAsm>(CI->getOperand(0))) return false;
+
// Resolve function pointers.
Function *Callee = dyn_cast<Function>(getVal(Values, CI->getOperand(0)));
if (!Callee) return false; // Cannot resolve.
-
- if (Callee->isExternal() || Callee->getFunctionType()->isVarArg()) {
- return false; // TODO: Constant fold calls.
- }
-
+
std::vector<Constant*> Formals;
for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
Formals.push_back(getVal(Values, CI->getOperand(i)));
- Constant *RetVal;
- // Execute the call, if successful, use the return value.
- if (!EvaluateFunction(Callee, RetVal, Formals, CallStack,
- MutatedMemory, AllocaTmps))
- return false;
- InstResult = RetVal;
+ if (Callee->isExternal()) {
+ // If this is a function we can constant fold, do it.
+ if (Constant *C = ConstantFoldCall(Callee, Formals)) {
+ InstResult = C;
+ } else {
+ return false;
+ }
+ } else {
+ if (Callee->getFunctionType()->isVarArg())
+ return false;
+
+ Constant *RetVal;
+
+ // Execute the call, if successful, use the return value.
+ if (!EvaluateFunction(Callee, RetVal, Formals, CallStack,
+ MutatedMemory, AllocaTmps))
+ return false;
+ InstResult = RetVal;
+ }
} else if (TerminatorInst *TI = dyn_cast<TerminatorInst>(CurInst)) {
BasicBlock *NewBB = 0;
if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {