Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
// some evil programs use sections as linker generated arrays
// read a description of this behavior in and apply it
// format: numglobals section globals...
// terminates when numglobals == 0
void handleMagicSections(DSGraph* GlobalsGraph, Module& M) {
  std::ifstream msf(hasMagicSections.c_str(), std::ifstream::in);
  if (msf.good()) {
    //no checking happens here
    unsigned count = 0;
    msf >> count;
    while (count) {
      std::string section;
      msf >> section;
      svset<Value*> inSection;
      for (Module::iterator MI = M.begin(), ME = M.end();
           MI != ME; ++MI)
        if (MI->hasSection() && MI->getSection() == section)
          inSection.insert(MI);
      for (Module::global_iterator MI = M.global_begin(), ME = M.global_end();
           MI != ME; ++MI)
        if (MI->hasSection() && MI->getSection() == section)
          inSection.insert(MI);

      for (unsigned x = 0; x < count; ++x) {
        std::string global;
        msf >> global;
        Value* V = M.getNamedValue(global);
        if (V) {
          DSNodeHandle& DHV = GlobalsGraph->getNodeForValue(V);
          for (svset<Value*>::iterator SI = inSection.begin(),
               SE = inSection.end(); SI != SE; ++SI) {
            DEBUG(errs() << "Merging " << V->getName().str() << " with "
                  << (*SI)->getName().str() << "\n");
            GlobalsGraph->getNodeForValue(*SI).mergeWith(DHV);
          }
        }
      }
      msf >> count;
    }
  } else {
Example #5
0
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;
}