本文整理汇总了C++中module::global_iterator::getType方法的典型用法代码示例。如果您正苦于以下问题:C++ global_iterator::getType方法的具体用法?C++ global_iterator::getType怎么用?C++ global_iterator::getType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类module::global_iterator
的用法示例。
在下文中一共展示了global_iterator::getType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: computeTypeMapping
/// computeTypeMapping - Loop over all of the linked values to compute type
/// mappings. For example, if we link "extern Foo *x" and "Foo *x = NULL", then
/// we have two struct types 'Foo' but one got renamed when the module was
/// loaded into the same LLVMContext.
void ModuleLinker::computeTypeMapping() {
// Incorporate globals.
for (Module::global_iterator I = SrcM->global_begin(),
E = SrcM->global_end(); I != E; ++I) {
GlobalValue *DGV = getLinkedToGlobal(I);
if (DGV == 0) continue;
if (!DGV->hasAppendingLinkage() || !I->hasAppendingLinkage()) {
TypeMap.addTypeMapping(DGV->getType(), I->getType());
continue;
}
// Unify the element type of appending arrays.
ArrayType *DAT = cast<ArrayType>(DGV->getType()->getElementType());
ArrayType *SAT = cast<ArrayType>(I->getType()->getElementType());
TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType());
}
// Incorporate functions.
for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) {
if (GlobalValue *DGV = getLinkedToGlobal(I))
TypeMap.addTypeMapping(DGV->getType(), I->getType());
}
// Incorporate types by name, scanning all the types in the source module.
// At this point, the destination module may have a type "%foo = { i32 }" for
// example. When the source module got loaded into the same LLVMContext, if
// it had the same type, it would have been renamed to "%foo.42 = { i32 }".
// Though it isn't required for correctness, attempt to link these up to clean
// up the IR.
std::vector<StructType*> SrcStructTypes;
SrcM->findUsedStructTypes(SrcStructTypes);
SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(),
SrcStructTypes.end());
for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) {
StructType *ST = SrcStructTypes[i];
if (!ST->hasName()) continue;
// Check to see if there is a dot in the name followed by a digit.
size_t DotPos = ST->getName().rfind('.');
if (DotPos == 0 || DotPos == StringRef::npos ||
ST->getName().back() == '.' || !isdigit(ST->getName()[DotPos+1]))
continue;
// Check to see if the destination module has a struct with the prefix name.
if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos)))
// Don't use it if this actually came from the source module. They're in
// the same LLVMContext after all.
if (!SrcStructTypesSet.count(DST))
TypeMap.addTypeMapping(DST, ST);
}
// Don't bother incorporating aliases, they aren't generally typed well.
// Now that we have discovered all of the type equivalences, get a body for
// any 'opaque' types in the dest module that are now resolved.
TypeMap.linkDefinedTypeBodies();
}
示例2: doInitialization
bool GlobalMerge::doInitialization(Module &M) {
DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals,
BSSGlobals;
const DataLayout *TD = TLI->getDataLayout();
unsigned MaxOffset = TLI->getMaximalGlobalOffset();
bool Changed = false;
// Grab all non-const globals.
for (Module::global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I) {
// Merge is safe for "normal" internal globals only
if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection())
continue;
PointerType *PT = dyn_cast<PointerType>(I->getType());
assert(PT && "Global variable is not a pointer!");
unsigned AddressSpace = PT->getAddressSpace();
// Ignore fancy-aligned globals for now.
unsigned Alignment = TD->getPreferredAlignment(I);
Type *Ty = I->getType()->getElementType();
if (Alignment > TD->getABITypeAlignment(Ty))
continue;
// Ignore all 'special' globals.
if (I->getName().startswith("llvm.") ||
I->getName().startswith(".llvm."))
continue;
if (TD->getTypeAllocSize(Ty) < MaxOffset) {
if (TargetLoweringObjectFile::getKindForGlobal(I, TLI->getTargetMachine())
.isBSSLocal())
BSSGlobals[AddressSpace].push_back(I);
else if (I->isConstant())
ConstGlobals[AddressSpace].push_back(I);
else
Globals[AddressSpace].push_back(I);
}
}
for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
I = Globals.begin(), E = Globals.end(); I != E; ++I)
if (I->second.size() > 1)
Changed |= doMerge(I->second, M, false, I->first);
for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I)
if (I->second.size() > 1)
Changed |= doMerge(I->second, M, false, I->first);
// FIXME: This currently breaks the EH processing due to way how the
// typeinfo detection works. We might want to detect the TIs and ignore
// them in the future.
// if (ConstGlobals.size() > 1)
// Changed |= doMerge(ConstGlobals, M, true);
return Changed;
}
示例3: checkFeatures
void MemoryInstrumenter::checkFeatures(Module &M) {
// Check whether any memory allocation function can
// potentially be pointed by function pointers.
// Also, all intrinsic functions will be called directly,
// i.e. not via function pointers.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) {
for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
User *Usr = *UI;
assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
CallSite CS(cast<Instruction>(Usr));
for (unsigned i = 0; i < CS.arg_size(); ++i)
assert(CS.getArgument(i) != F);
}
}
}
// Check whether memory allocation functions are captured.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
// 0 is the return, 1 is the first parameter.
if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << "'s return value is marked noalias, ";
errs() << "but the function is not treated as malloc.\n";
errs().resetColor();
}
}
// Sequential types except pointer types shouldn't be used as the type of
// an instruction, a function parameter, or a global variable.
for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
GI != E; ++GI) {
if (isa<SequentialType>(GI->getType()))
assert(GI->getType()->isPointerTy());
}
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
if (isa<SequentialType>(AI->getType()))
assert(AI->getType()->isPointerTy());
}
}
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
if (isa<SequentialType>(Ins->getType()))
assert(Ins->getType()->isPointerTy());
}
}
}
// We don't support multi-process programs for now.
if (!HookFork)
assert(M.getFunction("fork") == NULL);
}
示例4: SwitchToSection
void PIC16AsmPrinter::EmitRomData (Module &M)
{
SwitchToSection(TAI->getReadOnlySection());
IsRomData = true;
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (!I->hasInitializer()) // External global require no code.
continue;
Constant *C = I->getInitializer();
const PointerType *PtrTy = I->getType();
int AddrSpace = PtrTy->getAddressSpace();
if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) {
if (EmitSpecialLLVMGlobal(I))
continue;
// Any variables reaching here with "." in its name is a local scope
// variable and should not be printed in global data section.
std::string name = Mang->getValueName(I);
if (name.find(".") != std::string::npos)
continue;
I->setSection(TAI->getReadOnlySection()->getName());
O << name;
EmitGlobalConstant(C, AddrSpace);
O << "\n";
}
}
IsRomData = false;
}
示例5: AnalyzeGlobals
/// AnalyzeGlobals - Scan through the users of all of the internal
/// GlobalValue's in the program. If none of them have their "address taken"
/// (really, their address passed to something nontrivial), record this fact,
/// and record the functions that they are used directly in.
void GlobalsModRef::AnalyzeGlobals(Module &M) {
std::vector<Function*> Readers, Writers;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasLocalLinkage()) {
if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
// Remember that we are tracking this global.
NonAddressTakenGlobals.insert(I);
++NumNonAddrTakenFunctions;
}
Readers.clear(); Writers.clear();
}
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
if (I->hasLocalLinkage()) {
if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
// Remember that we are tracking this global, and the mod/ref fns
NonAddressTakenGlobals.insert(I);
for (unsigned i = 0, e = Readers.size(); i != e; ++i)
FunctionInfo[Readers[i]].GlobalInfo[I] |= Ref;
if (!I->isConstant()) // No need to keep track of writers to constants
for (unsigned i = 0, e = Writers.size(); i != e; ++i)
FunctionInfo[Writers[i]].GlobalInfo[I] |= Mod;
++NumNonAddrTakenGlobalVars;
// If this global holds a pointer type, see if it is an indirect global.
if (I->getType()->getElementType()->isPointerTy() &&
AnalyzeIndirectGlobalMemory(I))
++NumIndirectGlobalVars;
}
Readers.clear(); Writers.clear();
}
}
示例6: instrumentGlobals
void MemoryInstrumenter::instrumentGlobals(Module &M) {
TargetData &TD = getAnalysis<TargetData>();
IDAssigner &IDA = getAnalysis<IDAssigner>();
// Function HookGlobalsAlloc contains only one basic block.
// The BB iterates through all global variables, and calls HookMemAlloc
// for each of them.
BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry",
GlobalsAllocHook);
Instruction *Ret = ReturnInst::Create(M.getContext(), BB);
for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
GI != E; ++GI) {
// We are going to delete llvm.global_ctors.
// Therefore, don't instrument it.
if (GI->getName() == "llvm.global_ctors")
continue;
// Prevent global variables from sharing the same address, because it
// breaks the assumption that global variables do not alias.
// The same goes to functions.
if (GI->hasUnnamedAddr()) {
GI->setUnnamedAddr(false);
}
uint64_t TypeSize = TD.getTypeStoreSize(GI->getType()->getElementType());
instrumentMemoryAllocation(GI,
ConstantInt::get(LongType, TypeSize),
NULL,
Ret);
instrumentPointer(GI, NULL, Ret);
}
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
// These hooks added by us don't have a value ID.
if (MemAllocHook == F || MainArgsAllocHook == F || TopLevelHook == F ||
AddrTakenHook == F || CallHook == F || ReturnHook == F ||
GlobalsAllocHook == F || MemHooksIniter == F || AfterForkHook == F ||
BeforeForkHook == F) {
continue;
}
// InvalidID: maybe this is inserted by alias checker in hybrid mode.
if (IDA.getValueID(F) == IDAssigner::InvalidID)
continue;
// Ignore intrinsic functions because we cannot take the address of
// an intrinsic. Also, no function pointers will point to instrinsic
// functions.
if (F->isIntrinsic())
continue;
// Prevent functions from sharing the same address.
if (F->hasUnnamedAddr()) {
F->setUnnamedAddr(false);
}
uint64_t TypeSize = TD.getTypeStoreSize(F->getType());
assert(TypeSize == TD.getPointerSize());
instrumentMemoryAllocation(F,
ConstantInt::get(LongType, TypeSize),
NULL,
Ret);
instrumentPointer(F, NULL, Ret);
}
}
示例7: OptimizeGlobals
/// OptimizeGlobals - This method uses information taken from DSA to optimize
/// global variables.
///
bool DSOpt::OptimizeGlobals(Module &M) {
DSGraph* GG = TD->getGlobalsGraph();
const DSGraph::ScalarMapTy &SM = GG->getScalarMap();
bool Changed = false;
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
if (!I->isDeclaration()) { // Loop over all of the non-external globals...
// Look up the node corresponding to this global, if it exists.
DSNode *GNode = 0;
DSGraph::ScalarMapTy::const_iterator SMI = SM.find(I);
if (SMI != SM.end()) GNode = SMI->second.getNode();
if (GNode == 0 && I->hasInternalLinkage()) {
// If there is no entry in the scalar map for this global, it was never
// referenced in the program. If it has internal linkage, that means we
// can delete it. We don't ACTUALLY want to delete the global, just
// remove anything that references the global: later passes will take
// care of nuking it.
if (!I->use_empty()) {
I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
++NumGlobalsIsolated;
}
} else if (GNode && GNode->NodeType.isCompleteNode()) {
// If the node has not been read or written, and it is not externally
// visible, kill any references to it so it can be DCE'd.
if (!GNode->NodeType.isModifiedNode() && !GNode->NodeType.isReadNode() &&I->hasInternalLinkage()){
if (!I->use_empty()) {
I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
++NumGlobalsIsolated;
}
}
// We expect that there will almost always be a node for this global.
// If there is, and the node doesn't have the M bit set, we can set the
// 'constant' bit on the global.
if (!GNode->NodeType.isModifiedNode() && !I->isConstant()) {
I->setConstant(true);
++NumGlobalsConstanted;
Changed = true;
}
}
}
return Changed;
}
示例8: checkFeatures
void MemoryInstrumenter::checkFeatures(Module &M) {
// Check whether any memory allocation function can
// potentially be pointed by function pointers.
// Also, all intrinsic functions will be called directly,
// i.e. not via function pointers.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) {
for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
User *Usr = *UI;
assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
CallSite CS(cast<Instruction>(Usr));
for (unsigned i = 0; i < CS.arg_size(); ++i)
assert(CS.getArgument(i) != F);
}
}
}
// Check whether memory allocation functions are captured.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
// 0 is the return, 1 is the first parameter.
if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << "'s return value is marked noalias, ";
errs() << "but the function is not treated as malloc.\n";
errs().resetColor();
}
}
// Global variables shouldn't be of the array type.
for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
GI != E; ++GI) {
assert(!GI->getType()->isArrayTy());
}
// A function parameter or an instruction can be an array, but we don't
// instrument such constructs for now. Issue a warning on such cases.
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
if (AI->getType()->isArrayTy()) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << ":" << *AI << " is an array\n";
errs().resetColor();
}
}
}
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
if (Ins->getType()->isArrayTy()) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << ":" << *Ins << " is an array\n";
errs().resetColor();
}
}
}
}
}
示例9: identify_fixed_integers
void CaptureConstraints::identify_fixed_integers(Module &M) {
ExecOnce &EO = getAnalysis<ExecOnce>();
fixed_integers.clear();
// Global variables.
for (Module::global_iterator gi = M.global_begin();
gi != M.global_end(); ++gi) {
if (isa<IntegerType>(gi->getType()) || isa<PointerType>(gi->getType())) {
fixed_integers.insert(gi);
if (gi->hasInitializer())
extract_from_consts(gi->getInitializer());
}
}
// Instructions and their constant operands.
forallinst(M, ii) {
if (EO.not_executed(ii))
continue;
if (!EO.executed_once(ii))
continue;
if (isa<IntegerType>(ii->getType()) || isa<PointerType>(ii->getType())) {
fixed_integers.insert(ii);
}
// No matter reachable or not, capture its constant operands.
for (unsigned i = 0; i < ii->getNumOperands(); ++i) {
if (Constant *c = dyn_cast<Constant>(ii->getOperand(i)))
extract_from_consts(c);
}
}
// Function parameters.
forallfunc(M, f) {
if (EO.not_executed(f))
continue;
if (!EO.executed_once(f))
continue;
for (Function::arg_iterator ai = f->arg_begin();
ai != f->arg_end(); ++ai) {
if (isa<IntegerType>(ai->getType()) || isa<PointerType>(ai->getType()))
fixed_integers.insert(ai);
}
}
}
示例10: doInitialization
bool ARMGlobalMerge::doInitialization(Module &M) {
SmallVector<GlobalVariable*, 16> Globals, ConstGlobals, BSSGlobals;
const TargetData *TD = TLI->getTargetData();
unsigned MaxOffset = TLI->getMaximalGlobalOffset();
bool Changed = false;
// Disable this pass on darwin. The debugger is not yet ready to extract
// variable's info from a merged global.
if (TLI->getTargetMachine().getSubtarget<ARMSubtarget>().isTargetDarwin())
return false;
// Grab all non-const globals.
for (Module::global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I) {
// Merge is safe for "normal" internal globals only
if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection())
continue;
// Ignore fancy-aligned globals for now.
if (I->getAlignment() != 0)
continue;
// Ignore all 'special' globals.
if (I->getName().startswith("llvm.") ||
I->getName().startswith(".llvm."))
continue;
if (TD->getTypeAllocSize(I->getType()->getElementType()) < MaxOffset) {
const TargetLoweringObjectFile &TLOF = TLI->getObjFileLowering();
if (TLOF.getKindForGlobal(I, TLI->getTargetMachine()).isBSSLocal())
BSSGlobals.push_back(I);
else if (I->isConstant())
ConstGlobals.push_back(I);
else
Globals.push_back(I);
}
}
if (Globals.size() > 1)
Changed |= doMerge(Globals, M, false);
if (BSSGlobals.size() > 1)
Changed |= doMerge(BSSGlobals, M, false);
// FIXME: This currently breaks the EH processing due to way how the
// typeinfo detection works. We might want to detect the TIs and ignore
// them in the future.
// if (ConstGlobals.size() > 1)
// Changed |= doMerge(ConstGlobals, M, true);
return Changed;
}
示例11: initShadowGlobals
// Create shadow information for all global variables.
void LLPEAnalysisPass::initShadowGlobals(Module& M, uint32_t extraSlots) {
uint32_t i = 0;
uint32_t nGlobals = std::distance(M.global_begin(), M.global_end());
// extraSlots are reserved for new globals we know will be introduced between now and specialisation start.
nGlobals += extraSlots;
shadowGlobals = new ShadowGV[nGlobals];
// Assign them all numbers before computing initialisers, because the initialiser can
// reference another global, and getValPB will then lookup in shadowGlobalsIdx.
for(Module::global_iterator it = M.global_begin(), itend = M.global_end(); it != itend; ++it, ++i) {
shadowGlobals[i].G = it;
shadowGlobalsIdx[it] = i;
}
i = 0;
for(Module::global_iterator it = M.global_begin(), itend = M.global_end(); it != itend; ++it, ++i) {
// getTypeStoreSize can be expensive, so do it once here.
if(it->isConstant()) {
shadowGlobals[i].storeSize = GlobalAA->getTypeStoreSize(shadowGlobals[i].G->getType());
continue;
}
// Non-constant global -- assign it a heap slot.
shadowGlobals[i].allocIdx = (int32_t)heap.size();
heap.push_back(AllocData());
AllocData& AD = heap.back();
AD.allocIdx = heap.size() - 1;
AD.storeSize = GlobalAA->getTypeStoreSize(it->getType()->getElementType());
AD.isCommitted = true;
// This usually points to a malloc instruction -- here the global itself.
AD.allocValue = ShadowValue(&(shadowGlobals[i]));
AD.allocType = shadowGlobals[i].G->getType();
//errs() << "Init store for " << *it << " -> ";
//printPB(errs(), *Init);
//errs() << "\n";
shadowGlobals[i].storeSize = AD.storeSize;
}
}
示例12: printFields
/**
* Print the field declarations.
*/
void JVMWriter::printFields() {
out << "; Fields\n";
for(Module::global_iterator i = module->global_begin(),
e = module->global_end(); i != e; i++) {
if(i->isDeclaration()) {
out << ".extern field ";
externRefs.insert(i);
} else
out << ".field "
<< (i->hasLocalLinkage() ? "private " : "public ")
<< "static final ";
out << getValueName(i) << ' ' << getTypeDescriptor(i->getType());
if(debug >= 3)
out << " ; " << *i;
else
out << '\n';
}
out << '\n';
}
示例13: doInitialization
bool ARMGlobalMerge::doInitialization(Module &M) {
SmallVector<GlobalVariable*, 16> Globals, ConstGlobals;
const TargetData *TD = TLI->getTargetData();
unsigned MaxOffset = TLI->getMaximalGlobalOffset();
bool Changed = false;
// Grab all non-const globals.
for (Module::global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I) {
// Merge is safe for "normal" internal globals only
if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection())
continue;
// Ignore fancy-aligned globals for now.
if (I->getAlignment() != 0)
continue;
// Ignore all 'special' globals.
if (I->getName().startswith("llvm.") ||
I->getName().startswith(".llvm."))
continue;
if (TD->getTypeAllocSize(I->getType()) < MaxOffset) {
if (I->isConstant())
ConstGlobals.push_back(I);
else
Globals.push_back(I);
}
}
if (Globals.size() > 1)
Changed |= doMerge(Globals, M, false);
// FIXME: This currently breaks the EH processing due to way how the
// typeinfo detection works. We might want to detect the TIs and ignore
// them in the future.
// if (ConstGlobals.size() > 1)
// Changed |= doMerge(ConstGlobals, M, true);
return Changed;
}
示例14: doInitialization
bool GlobalMerge::doInitialization(Module &M) {
if (!EnableGlobalMerge)
return false;
auto &DL = M.getDataLayout();
DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals,
BSSGlobals;
bool Changed = false;
setMustKeepGlobalVariables(M);
// Grab all non-const globals.
for (Module::global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I) {
// Merge is safe for "normal" internal or external globals only
if (I->isDeclaration() || I->isThreadLocal() || I->hasSection())
continue;
if (!(EnableGlobalMergeOnExternal && I->hasExternalLinkage()) &&
!I->hasInternalLinkage())
continue;
PointerType *PT = dyn_cast<PointerType>(I->getType());
assert(PT && "Global variable is not a pointer!");
unsigned AddressSpace = PT->getAddressSpace();
// Ignore fancy-aligned globals for now.
unsigned Alignment = DL.getPreferredAlignment(I);
Type *Ty = I->getType()->getElementType();
if (Alignment > DL.getABITypeAlignment(Ty))
continue;
// Ignore all 'special' globals.
if (I->getName().startswith("llvm.") ||
I->getName().startswith(".llvm."))
continue;
// Ignore all "required" globals:
if (isMustKeepGlobalVariable(I))
continue;
if (DL.getTypeAllocSize(Ty) < MaxOffset) {
if (TargetLoweringObjectFile::getKindForGlobal(I, *TM).isBSSLocal())
BSSGlobals[AddressSpace].push_back(I);
else if (I->isConstant())
ConstGlobals[AddressSpace].push_back(I);
else
Globals[AddressSpace].push_back(I);
}
}
for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
I = Globals.begin(), E = Globals.end(); I != E; ++I)
if (I->second.size() > 1)
Changed |= doMerge(I->second, M, false, I->first);
for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I)
if (I->second.size() > 1)
Changed |= doMerge(I->second, M, false, I->first);
if (EnableGlobalMergeOnConst)
for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
I = ConstGlobals.begin(), E = ConstGlobals.end(); I != E; ++I)
if (I->second.size() > 1)
Changed |= doMerge(I->second, M, true, I->first);
return Changed;
}
示例15: runOnModule
bool AllocateDataSegment::runOnModule(Module &M) {
DataLayout DL(&M);
Type *I8 = Type::getInt8Ty(M.getContext());
Type *I32 = Type::getInt32Ty(M.getContext());
Type *IntPtrType = DL.getIntPtrType(M.getContext());
// First, we do a pass over the global variables, in which we compute
// the amount of required padding between them and consequently their
// addresses relative to the memory base of the sandbox. References to each
// global are then replaced with direct memory pointers.
uint32_t VarOffset = 0;
DenseMap<GlobalVariable*, uint32_t> VarPadding;
for (Module::global_iterator GV = M.global_begin(), E = M.global_end();
GV != E; ++GV) {
assert(GV->hasInitializer());
uint32_t Padding = getPadding(VarOffset, GV, DL);
VarPadding[GV] = Padding;
VarOffset += Padding;
GV->replaceAllUsesWith(
ConstantExpr::getIntToPtr(
ConstantInt::get(IntPtrType,
DataSegmentBaseAddress + VarOffset),
GV->getType()));
VarOffset += DL.getTypeStoreSize(GV->getType()->getPointerElementType());
}
// Using the offsets computed above, we prepare the layout and the contents
// of the desired data structure. After the type and initializer of each
// global is copied, the global is not needed any more and it is erased.
SmallVector<Type*, 10> TemplateLayout;
SmallVector<Constant*, 10> TemplateData;
for (Module::global_iterator It = M.global_begin(), E = M.global_end();
It != E; ) {
GlobalVariable *GV = It++;
uint32_t Padding = VarPadding[GV];
if (Padding > 0) {
Type *PaddingType = ArrayType::get(I8, Padding);
TemplateLayout.push_back(PaddingType);
TemplateData.push_back(ConstantAggregateZero::get(PaddingType));
}
TemplateLayout.push_back(GV->getType()->getPointerElementType());
TemplateData.push_back(GV->getInitializer());
GV->eraseFromParent();
}
// Finally, we create the struct and size global variables.
StructType *TemplateType =
StructType::create(M.getContext(), ExternalSymName_DataSegment);
TemplateType->setBody(TemplateLayout, /*isPacked=*/true);
Constant *Template = ConstantStruct::get(TemplateType, TemplateData);
new GlobalVariable(M, Template->getType(), /*isConstant=*/true,
GlobalVariable::ExternalLinkage, Template,
ExternalSymName_DataSegment);
Constant *TemplateSize =
ConstantInt::get(I32, DL.getTypeAllocSize(TemplateType));
new GlobalVariable(M, TemplateSize->getType(), /*isConstant=*/true,
GlobalVariable::ExternalLinkage, TemplateSize,
ExternalSymName_DataSegmentSize);
return true;
}