From d39c594d39df7f283c2fb8a704a3f31c501180d9 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 17 Sep 2010 15:48:55 +0000 Subject: Vendor import of llvm r114020 (from the release_28 branch): http://llvm.org/svn/llvm-project/llvm/branches/release_28@114020 Approved by: rpaulo (mentor) --- lib/Transforms/IPO/ConstantMerge.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'lib/Transforms/IPO/ConstantMerge.cpp') diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index 3c05f88027a62..64e8d792dc3ad 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -19,10 +19,12 @@ #define DEBUG_TYPE "constmerge" #include "llvm/Transforms/IPO.h" +#include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -31,7 +33,7 @@ STATISTIC(NumMerged, "Number of global constants merged"); namespace { struct ConstantMerge : public ModulePass { static char ID; // Pass identification, replacement for typeid - ConstantMerge() : ModulePass(&ID) {} + ConstantMerge() : ModulePass(ID) {} // run - For this pass, process all of the globals in the module, // eliminating duplicate constants. @@ -41,12 +43,32 @@ namespace { } char ConstantMerge::ID = 0; -static RegisterPass -X("constmerge", "Merge Duplicate Global Constants"); +INITIALIZE_PASS(ConstantMerge, "constmerge", + "Merge Duplicate Global Constants", false, false); ModulePass *llvm::createConstantMergePass() { return new ConstantMerge(); } + + +/// Find values that are marked as llvm.used. +static void FindUsedValues(GlobalVariable *LLVMUsed, + SmallPtrSet &UsedValues) { + if (LLVMUsed == 0) return; + ConstantArray *Inits = dyn_cast(LLVMUsed->getInitializer()); + if (Inits == 0) return; + + for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) + if (GlobalValue *GV = + dyn_cast(Inits->getOperand(i)->stripPointerCasts())) + UsedValues.insert(GV); +} + bool ConstantMerge::runOnModule(Module &M) { + // Find all the globals that are marked "used". These cannot be merged. + SmallPtrSet UsedGlobals; + FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals); + FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals); + // Map unique constant/section pairs to globals. We don't want to merge // globals in different sections. DenseMap CMap; @@ -79,9 +101,13 @@ bool ConstantMerge::runOnModule(Module &M) { // Only process constants with initializers in the default addres space. if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() || - GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty()) + GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty() || + // Don't touch values marked with attribute(used). + UsedGlobals.count(GV)) continue; + + Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. -- cgit v1.2.3