void LTOCodeGenerator::applyScopeRestrictions()
{
    if ( !_scopeRestrictionsDone ) {
        Module* mergedModule = _linker.getModule();

        // Start off with a verification pass.
        PassManager passes;
        passes.add(createVerifierPass());

        // mark which symbols can not be internalized 
        if ( !_mustPreserveSymbols.empty() ) {
            Mangler mangler(*mergedModule, 
                                _target->getTargetAsmInfo()->getGlobalPrefix());
            std::vector<const char*> mustPreserveList;
            for (Module::iterator f = mergedModule->begin(), 
                                        e = mergedModule->end(); f != e; ++f) {
                if ( !f->isDeclaration() 
                  && _mustPreserveSymbols.count(mangler.getMangledName(f)) )
                  mustPreserveList.push_back(::strdup(f->getNameStr().c_str()));
            }
            for (Module::global_iterator v = mergedModule->global_begin(), 
                                 e = mergedModule->global_end(); v !=  e; ++v) {
                if ( !v->isDeclaration()
                  && _mustPreserveSymbols.count(mangler.getMangledName(v)) )
                  mustPreserveList.push_back(::strdup(v->getNameStr().c_str()));
            }
            passes.add(createInternalizePass(mustPreserveList));
        }
        // apply scope restrictions
        passes.run(*mergedModule);
        
        _scopeRestrictionsDone = true;
    }
}
Пример #2
0
/**
 * Print the static class initialization method.
 */
void JVMWriter::printClInit() {
    //out << ".method public <clinit>()V\n";
    out << ".method public initialiseEnvironment(Llljvm/runtime/Environment;)V\n";
    printSimpleInstruction(".limit stack 5");
    printSimpleInstruction(".limit locals 2");
    
    out << "\n\t; load environment into class\n";
    printSimpleInstruction("aload_0"); // this.
    printSimpleInstruction("aload_1"); // value
    printSimpleInstruction("putfield "+classname+"/__env Llljvm/runtime/Environment;");
    
    out << "\n\t; allocate global variables\n";
    for(Module::global_iterator i = module->global_begin(),
                                e = module->global_end(); i != e; i++) {
        if(!i->isDeclaration()) {
            const GlobalVariable *g = i;
            const Constant *c = g->getInitializer();
            printLoadMemoryToStack();
            printConstLoad(
                APInt(32, targetData->getTypeAllocSize(c->getType()), false));
            printSimpleInstruction("invokevirtual",
                                   "lljvm/runtime/Memory/allocateData(I)I");
            printSimpleInstruction("aload_0"); // "this"
            printSimpleInstruction("swap"); // move this 1 down the stack
            printSimpleInstruction("putfield",
                classname + "/" + getValueName(g) + " I");
        }
    }
    
    out << "\n\t; initialise global variables\n";
    for(Module::global_iterator i = module->global_begin(),
                                e = module->global_end(); i != e; i++) {
        if(!i->isDeclaration()) {
            const GlobalVariable *g = i;
            const Constant *c = g->getInitializer();
            printSimpleInstruction("aload_0"); // "this"
            printSimpleInstruction("getfield",
                classname + "/" + getValueName(g) + " I");
            printStaticConstant(c);
            printSimpleInstruction("pop");
            out << '\n';
        }
    }
    
    printSimpleInstruction("return");
    out << ".end method\n\n";
}
Пример #3
0
/**
 * Print the static class initialization method.
 */
void JVMWriter::printClInit() {
    out << ".method public <clinit>()V\n";
    printSimpleInstruction(".limit stack 4");
    
    out << "\n\t; allocate global variables\n";
    for(Module::global_iterator i = module->global_begin(),
                                e = module->global_end(); i != e; i++) {
        if(!i->isDeclaration()) {
            const GlobalVariable *g = i;
            const Constant *c = g->getInitializer();
            printConstLoad(
                APInt(32, targetData->getTypeAllocSize(c->getType()), false));
            printSimpleInstruction("invokestatic",
                                   "lljvm/runtime/Memory/allocateData(I)I");
            printSimpleInstruction("putstatic",
                classname + "/" + getValueName(g) + " I");
        }
    }
    
    out << "\n\t; initialise global variables\n";
    for(Module::global_iterator i = module->global_begin(),
                                e = module->global_end(); i != e; i++) {
        if(!i->isDeclaration()) {
            const GlobalVariable *g = i;
            const Constant *c = g->getInitializer();
            printSimpleInstruction("getstatic",
                classname + "/" + getValueName(g) + " I");
            printStaticConstant(c);
            printSimpleInstruction("pop");
            out << '\n';
        }
    }
    
    printSimpleInstruction("return");
    out << ".end method\n\n";
}
Пример #4
0
/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still
/// exist in an LLVM module. This is a bit tricky because there may be two
/// symbols with the same name but different LLVM types that will be resolved to
/// each other but aren't currently (thus we need to treat it as resolved).
///
/// Inputs:
///  M - The module in which to find undefined symbols.
///
/// Outputs:
///  UndefinedSymbols - A set of C++ strings containing the name of all
///                     undefined symbols.
///
static void
GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
  std::set<std::string> DefinedSymbols;
  UndefinedSymbols.clear();

  // If the program doesn't define a main, try pulling one in from a .a file.
  // This is needed for programs where the main function is defined in an
  // archive, such f2c'd programs.
  Function *Main = M->getFunction("main");
  if (Main == 0 || Main->isDeclaration())
    UndefinedSymbols.insert("main");

  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (I->hasName()) {
      if (I->isDeclaration())
        UndefinedSymbols.insert(I->getName());
      else if (!I->hasLocalLinkage()) {
        assert(!I->hasDLLImportLinkage()
               && "Found dllimported non-external symbol!");
        DefinedSymbols.insert(I->getName());
      }      
    }

  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I)
    if (I->hasName()) {
      if (I->isDeclaration())
        UndefinedSymbols.insert(I->getName());
      else if (!I->hasLocalLinkage()) {
        assert(!I->hasDLLImportLinkage()
               && "Found dllimported non-external symbol!");
        DefinedSymbols.insert(I->getName());
      }      
    }

  for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I)
    if (I->hasName())
      DefinedSymbols.insert(I->getName());

  // Prune out any defined symbols from the undefined symbols set...
  for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
       I != UndefinedSymbols.end(); )
    if (DefinedSymbols.count(*I))
      UndefinedSymbols.erase(I++);  // This symbol really is defined!
    else
      ++I; // Keep this symbol in the undefined symbols list
}
void
AndroidBitcodeLinker::GetAllSymbols(Module *M,
  std::set<std::string> &UndefinedSymbols,
  std::set<std::string> &DefinedSymbols) {

  UndefinedSymbols.clear();
  DefinedSymbols.clear();

  Function *Main = M->getFunction("main");
  if (Main == 0 || Main->isDeclaration())
    UndefinedSymbols.insert("main");

  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (I->hasName()) {
      if (I->isDeclaration())
        UndefinedSymbols.insert(I->getName());
      else if (!I->hasLocalLinkage()) {
        assert(!I->hasDLLImportStorageClass()
               && "Found dllimported non-external symbol!");
        DefinedSymbols.insert(I->getName());
      }
    }

  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I)
    if (I->hasName()) {
      if (I->isDeclaration())
        UndefinedSymbols.insert(I->getName());
      else if (!I->hasLocalLinkage()) {
        assert(!I->hasDLLImportStorageClass()
               && "Found dllimported non-external symbol!");
        DefinedSymbols.insert(I->getName());
      }
    }

  for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I)
    if (I->hasName())
      DefinedSymbols.insert(I->getName());

  for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
       I != UndefinedSymbols.end(); )
    if (DefinedSymbols.count(*I))
      UndefinedSymbols.erase(I++);
    else
      ++I;
}
Пример #6
0
bool StripExternals::runOnModule(Module &M) {
  bool Changed = false;

  for (Module::iterator I = M.begin(); I != M.end(); ) {
    if (I->hasAvailableExternallyLinkage()) {
      assert(!I->isDeclaration()&&"Declarations can't be available_externally");
      Changed = true;
      ++NumFunctions;
      if (I->use_empty()) {
        DEBUG(errs() << "Deleting function: " << *I);
        Module::iterator todelete = I;
        ++I;
        todelete->eraseFromParent();
        continue;
      } else {
        I->deleteBody();
        DEBUG(errs() << "Deleted function body: " << *I);
      }
    }
    ++I;
  }

  for (Module::global_iterator I = M.global_begin();
       I != M.global_end(); ) {
    if (I->hasAvailableExternallyLinkage()) {
      assert(!I->isDeclaration()&&"Declarations can't be available_externally");
      Changed = true;
      ++NumVariables;
      if (I->use_empty()) {
        DEBUG(errs() << "Deleting global: " << *I);
        Module::global_iterator todelete = I;
        ++I;
        todelete->eraseFromParent();
        continue;
      } else {
        I->setInitializer(0);
        I->setLinkage(GlobalValue::ExternalLinkage);
        DEBUG(errs() << "Deleted initializer: " << *I);
      }
    }
    ++I;
  }

  return Changed;
}
Пример #7
0
/// 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
0
/**
 * 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';
}
static void getSymbols(Module*M, std::vector<std::string>& symbols) {
    // Loop over global variables
    for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI)
        if (!GI->isDeclaration() && !GI->hasLocalLinkage())
            if (!GI->getName().empty())
                symbols.push_back(GI->getName());

    // Loop over functions
    for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI)
        if (!FI->isDeclaration() && !FI->hasLocalLinkage())
            if (!FI->getName().empty())
                symbols.push_back(FI->getName());

    // Loop over aliases
    for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end();
            AI != AE; ++AI) {
        if (AI->hasName())
            symbols.push_back(AI->getName());
    }
}
/// doInitialization - Perform Module level initializations here.
/// One task that we do here is to sectionize all global variables.
/// The MemSelOptimizer pass depends on the sectionizing.
///
bool PIC16AsmPrinter::doInitialization(Module &M) {
  bool Result = AsmPrinter::doInitialization(M);

  // Every asmbly contains these std headers. 
  O << "\n#include p16f1xxx.inc";
  O << "\n#include stdmacros.inc";

  // Set the section names for all globals.
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {

    // Record External Var Decls.
    if (I->isDeclaration()) {
      ExternalVarDecls.push_back(I);
      continue;
    }

    // Record Exteranl Var Defs.
    if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
      ExternalVarDefs.push_back(I);
    }

    // Sectionify actual data.
    if (!I->hasAvailableExternallyLinkage()) {
      const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
      
      I->setSection(((const PIC16Section *)S)->getName());
    }
  }

  DbgInfo.BeginModule(M);
  EmitFunctionDecls(M);
  EmitUndefinedVars(M);
  EmitDefinedVars(M);
  EmitIData(M);
  EmitUData(M);
  EmitRomData(M);
  EmitSharedUdata(M);
  EmitUserSections(M);
  return Result;
}
Пример #11
0
void LTOModule::lazyParseSymbols()
{
    if ( !_symbolsParsed ) {
        _symbolsParsed = true;
        
        // Use mangler to add GlobalPrefix to names to match linker names.
        Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix());

        // add functions
        for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
            if ( f->isDeclaration() ) 
                addPotentialUndefinedSymbol(f, mangler);
            else 
                addDefinedFunctionSymbol(f, mangler);
        }
        
        // add data 
        for (Module::global_iterator v = _module->global_begin(), 
                                    e = _module->global_end(); v !=  e; ++v) {
            if ( v->isDeclaration() ) 
                addPotentialUndefinedSymbol(v, mangler);
            else 
                addDefinedDataSymbol(v, mangler);
        }

        // make symbols for all undefines
        for (StringSet::iterator it=_undefines.begin(); 
                                                it != _undefines.end(); ++it) {
            // if this symbol also has a definition, then don't make an undefine
            // because it is a tentative definition
            if ( _defines.count(it->getKeyData(), it->getKeyData()+
                                                  it->getKeyLength()) == 0 ) {
                NameAndAttributes info;
                info.name = it->getKeyData();
                info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
                _symbols.push_back(info);
            }
        }
    }    
}
Пример #12
0
bool InternalizePass::runOnModule(Module &M) {
  CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
  CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
  bool Changed = false;

  // Never internalize functions which code-gen might insert.
  // FIXME: We should probably add this (and the __stack_chk_guard) via some
  // type of call-back in CodeGen.
  ExternalNames.insert("__stack_chk_fail");

  // Mark all functions not in the api as internal.
  // FIXME: maybe use private linkage?
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() &&         // Function must be defined here
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !I->hasLocalLinkage() &&  // Can't already have internal linkage
        !ExternalNames.count(I->getName())) {// Not marked to keep external?
      I->setLinkage(GlobalValue::InternalLinkage);
      // Remove a callgraph edge from the external node to this function.
      if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]);
      Changed = true;
      ++NumFunctions;
      DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n");
    }

  // Never internalize the llvm.used symbol.  It is used to implement
  // attribute((used)).
  // FIXME: Shouldn't this just filter on llvm.metadata section??
  ExternalNames.insert("llvm.used");
  ExternalNames.insert("llvm.compiler.used");

  // Never internalize anchors used by the machine module info, else the info
  // won't find them.  (see MachineModuleInfo.)
  ExternalNames.insert("llvm.global_ctors");
  ExternalNames.insert("llvm.global_dtors");
  ExternalNames.insert("llvm.global.annotations");

  // Never internalize symbols code-gen inserts.
  ExternalNames.insert("__stack_chk_guard");

  // Mark all global variables with initializers that are not in the api as
  // internal as well.
  // FIXME: maybe use private linkage?
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasLocalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumGlobals;
      DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n");
    }

  // Mark all aliases that are not in the api as internal as well.
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasInternalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumAliases;
      DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n");
    }

  return Changed;
}
Пример #13
0
bool GlobalDCE::runOnModule(Module &M) {
  bool Changed = false;
  
  // Loop over the module, adding globals which are obviously necessary.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Functions with external linkage are needed if they have a body
    if (!I->isDiscardableIfUnused() &&
        !I->isDeclaration() && !I->hasAvailableExternallyLinkage())
      GlobalIsNeeded(I);
  }

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Externally visible & appending globals are needed, if they have an
    // initializer.
    if (!I->isDiscardableIfUnused() &&
        !I->isDeclaration() && !I->hasAvailableExternallyLinkage())
      GlobalIsNeeded(I);
  }

  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Externally visible aliases are needed.
    if (!I->isDiscardableIfUnused())
      GlobalIsNeeded(I);
  }

  // Now that all globals which are needed are in the AliveGlobals set, we loop
  // through the program, deleting those which are not alive.
  //

  // The first pass is to drop initializers of global variables which are dead.
  std::vector<GlobalVariable*> DeadGlobalVars;   // Keep track of dead globals
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!AliveGlobals.count(I)) {
      DeadGlobalVars.push_back(I);         // Keep track of dead globals
      I->setInitializer(0);
    }

  // The second pass drops the bodies of functions which are dead...
  std::vector<Function*> DeadFunctions;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!AliveGlobals.count(I)) {
      DeadFunctions.push_back(I);         // Keep track of dead globals
      if (!I->isDeclaration())
        I->deleteBody();
    }

  // The third pass drops targets of aliases which are dead...
  std::vector<GlobalAlias*> DeadAliases;
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
       ++I)
    if (!AliveGlobals.count(I)) {
      DeadAliases.push_back(I);
      I->setAliasee(0);
    }

  if (!DeadFunctions.empty()) {
    // Now that all interferences have been dropped, delete the actual objects
    // themselves.
    for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadFunctions[i]);
      M.getFunctionList().erase(DeadFunctions[i]);
    }
    NumFunctions += DeadFunctions.size();
    Changed = true;
  }

  if (!DeadGlobalVars.empty()) {
    for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
      M.getGlobalList().erase(DeadGlobalVars[i]);
    }
    NumVariables += DeadGlobalVars.size();
    Changed = true;
  }

  // Now delete any dead aliases.
  if (!DeadAliases.empty()) {
    for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadAliases[i]);
      M.getAliasList().erase(DeadAliases[i]);
    }
    NumAliases += DeadAliases.size();
    Changed = true;
  }

  // Make sure that all memory is released
  AliveGlobals.clear();

  return Changed;
}
Пример #14
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;
}
Пример #15
0
/// Based on GetAllUndefinedSymbols() from LLVM3.2
///
/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still
/// exist in an LLVM module. This is a bit tricky because there may be two
/// symbols with the same name but different LLVM types that will be resolved to
/// each other but aren't currently (thus we need to treat it as resolved).
///
/// Inputs:
///  M - The module in which to find undefined symbols.
///
/// Outputs:
///  UndefinedSymbols - A set of C++ strings containing the name of all
///                     undefined symbols.
///
static void
GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
    static const std::string llvmIntrinsicPrefix="llvm.";
    std::set<std::string> DefinedSymbols;
    UndefinedSymbols.clear();
    KLEE_DEBUG_WITH_TYPE("klee_linker",
                         dbgs() << "*** Computing undefined symbols ***\n");

    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
        if (I->hasName()) {
            if (I->isDeclaration())
                UndefinedSymbols.insert(I->getName());
            else if (!I->hasLocalLinkage()) {
#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
                assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!");
#else
                assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!");
#endif
                DefinedSymbols.insert(I->getName());
            }
        }

    for (Module::global_iterator I = M->global_begin(), E = M->global_end();
            I != E; ++I)
        if (I->hasName()) {
            if (I->isDeclaration())
                UndefinedSymbols.insert(I->getName());
            else if (!I->hasLocalLinkage()) {
#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
                assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!");
#else
                assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!");
#endif
                DefinedSymbols.insert(I->getName());
            }
        }

    for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
            I != E; ++I)
        if (I->hasName())
            DefinedSymbols.insert(I->getName());


    // Prune out any defined symbols from the undefined symbols set
    // and other symbols we don't want to treat as an undefined symbol
    std::vector<std::string> SymbolsToRemove;
    for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
            I != UndefinedSymbols.end(); ++I )
    {
        if (DefinedSymbols.count(*I))
        {
            SymbolsToRemove.push_back(*I);
            continue;
        }

        // Strip out llvm intrinsics
        if ( (I->size() >= llvmIntrinsicPrefix.size() ) &&
                (I->compare(0, llvmIntrinsicPrefix.size(), llvmIntrinsicPrefix) == 0) )
        {
            KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "LLVM intrinsic " << *I <<
                                 " has will be removed from undefined symbols"<< "\n");
            SymbolsToRemove.push_back(*I);
            continue;
        }

        // Symbol really is undefined
        KLEE_DEBUG_WITH_TYPE("klee_linker",
                             dbgs() << "Symbol " << *I << " is undefined.\n");
    }

    // Remove KLEE intrinsics from set of undefined symbols
    for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(),
            se = SpecialFunctionHandler::end(); sf != se; ++sf)
    {
        if (UndefinedSymbols.find(sf->name) == UndefinedSymbols.end())
            continue;

        SymbolsToRemove.push_back(sf->name);
        KLEE_DEBUG_WITH_TYPE("klee_linker",
                             dbgs() << "KLEE intrinsic " << sf->name <<
                             " has will be removed from undefined symbols"<< "\n");
    }

    // Now remove the symbols from undefined set.
    for (size_t i = 0, j = SymbolsToRemove.size(); i < j; ++i )
        UndefinedSymbols.erase(SymbolsToRemove[i]);

    KLEE_DEBUG_WITH_TYPE("klee_linker",
                         dbgs() << "*** Finished computing undefined symbols ***\n");
}
Пример #16
0
int main(int argc, char **argv) {
  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n");

  std::string ErrorMessage;
  std::auto_ptr<Module> M;

  {
    OwningPtr<MemoryBuffer> BufferPtr;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
      ErrorMessage = ec.message();
    else
      M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
  }

  if (M.get() == 0) {
    errs() << argv[0] << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "bitcode didn't read correctly.\n";
    return 1;
  }

  // Set linkage of every external definition to linkonce_odr.
  for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
    if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage) {
      i->setLinkage(GlobalValue::LinkOnceODRLinkage);
      //i->addFnAttr(Attributes::AlwaysInline);
    }
  }

  for (Module::global_iterator i = M->global_begin(), e = M->global_end();
       i != e; ++i) {
    if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage) {
      i->setLinkage(GlobalValue::LinkOnceAnyLinkage);
    }
  }

  if (OutputFilename.empty()) {
    errs() << "no output file\n";
    return 1;
  }

  std::string ErrorInfo;
  OwningPtr<tool_output_file> Out
  (new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                        raw_fd_ostream::F_Binary));
  if (!ErrorInfo.empty()) {
    errs() << ErrorInfo << '\n';
    exit(1);
  }

  WriteBitcodeToFile(M.get(), Out->os());

  // Declare success.
  Out->keep();
  return 0;
}
Пример #17
0
/// InputFilename is a LLVM bitcode file. Read it using bitcode reader.
/// Collect global functions and symbol names in symbols vector.
/// Collect external references in references vector.
/// Return LTO_READ_SUCCESS if there is no error.
enum LTOStatus
LTO::readLLVMObjectFile(const std::string &InputFilename,
                        NameToSymbolMap &symbols,
                        std::set<std::string> &references)
{
  Module *m = getModule(InputFilename);
  if (!m)
    return LTO_READ_FAILURE;

  // Collect Target info
  getTarget(m);

  if (!Target)
    return LTO_READ_FAILURE;
  
  // Use mangler to add GlobalPrefix to names to match linker names.
  // FIXME : Instead of hard coding "-" use GlobalPrefix.
  Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix());
  modules.push_back(m);
  
  for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) {
    LTOLinkageTypes lt = getLTOLinkageType(f);
    LTOVisibilityTypes vis = getLTOVisibilityType(f);
    if (!f->isDeclaration() && lt != LTOInternalLinkage
        && strncmp (f->getName().c_str(), "llvm.", 5)) {
      int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment());
      LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, f, f->getName(), 
                                             mangler.getValueName(f),
                                             Log2_32(alignment));
      symbols[newSymbol->getMangledName()] = newSymbol;
      allSymbols[newSymbol->getMangledName()] = newSymbol;
    }

    // Collect external symbols referenced by this function.
    for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b) 
      for (BasicBlock::iterator i = b->begin(), be = b->end(); 
           i != be; ++i) {
        for (unsigned count = 0, total = i->getNumOperands(); 
             count != total; ++count)
          findExternalRefs(i->getOperand(count), references, mangler);
      }
  }
    
  for (Module::global_iterator v = m->global_begin(), e = m->global_end();
       v !=  e; ++v) {
    LTOLinkageTypes lt = getLTOLinkageType(v);
    LTOVisibilityTypes vis = getLTOVisibilityType(v);
    if (!v->isDeclaration() && lt != LTOInternalLinkage
        && strncmp (v->getName().c_str(), "llvm.", 5)) {
      const TargetData *TD = Target->getTargetData();
      LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, v, v->getName(), 
                                             mangler.getValueName(v),
                                             TD->getPreferredAlignmentLog(v));
      symbols[newSymbol->getMangledName()] = newSymbol;
      allSymbols[newSymbol->getMangledName()] = newSymbol;

      for (unsigned count = 0, total = v->getNumOperands(); 
           count != total; ++count)
        findExternalRefs(v->getOperand(count), references, mangler);

    }
  }
  
  return LTO_READ_SUCCESS;
}
Пример #18
0
bool InternalizePass::runOnModule(Module &M) {
  CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
  CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
  
  if (ExternalNames.empty()) {
    // Return if we're not in 'all but main' mode and have no external api
    if (!AllButMain)
      return false;
    // If no list or file of symbols was specified, check to see if there is a
    // "main" symbol defined in the module.  If so, use it, otherwise do not
    // internalize the module, it must be a library or something.
    //
    Function *MainFunc = M.getFunction("main");
    if (MainFunc == 0 || MainFunc->isDeclaration())
      return false;  // No main found, must be a library...

    // Preserve main, internalize all else.
    ExternalNames.insert(MainFunc->getName());
  }

  bool Changed = false;

  // Never internalize functions which code-gen might insert.
  ExternalNames.insert("__stack_chk_fail");

  // Mark all functions not in the api as internal.
  // FIXME: maybe use private linkage?
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() &&         // Function must be defined here
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !I->hasLocalLinkage() &&  // Can't already have internal linkage
        !ExternalNames.count(I->getName())) {// Not marked to keep external?
      I->setLinkage(GlobalValue::InternalLinkage);
      // Remove a callgraph edge from the external node to this function.
      if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]);
      Changed = true;
      ++NumFunctions;
      DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n");
    }

  // Never internalize the llvm.used symbol.  It is used to implement
  // attribute((used)).
  // FIXME: Shouldn't this just filter on llvm.metadata section??
  ExternalNames.insert("llvm.used");
  ExternalNames.insert("llvm.compiler.used");

  // Never internalize anchors used by the machine module info, else the info
  // won't find them.  (see MachineModuleInfo.)
  ExternalNames.insert("llvm.global_ctors");
  ExternalNames.insert("llvm.global_dtors");
  ExternalNames.insert("llvm.global.annotations");

  // Never internalize symbols code-gen inserts.
  ExternalNames.insert("__stack_chk_guard");

  // Mark all global variables with initializers that are not in the api as
  // internal as well.
  // FIXME: maybe use private linkage?
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasLocalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumGlobals;
      DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n");
    }

  // Mark all aliases that are not in the api as internal as well.
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasInternalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumAliases;
      DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n");
    }

  return Changed;
}
Пример #19
0
/**
 * Print the class constructor.
 */
void JVMWriter::printConstructor() {
    out << "; Constructor\n"
           ".method public <init>()V\n";
    printSimpleInstruction("aload_0");
    printSimpleInstruction("invokespecial","java/lang/Object/<init>()V");
    printSimpleInstruction("return");
    printSimpleInstruction(".limit stack 1");
    printSimpleInstruction(".limit locals 1");
    out << ".end method\n\n";
    
    out << ".method public initialize(Llljvm/runtime/Context;)V\n";

    printSimpleInstruction(".limit stack 12");
    printSimpleInstruction(".limit locals 2");

    out << "\n;;;START LINKER INITIALIZATIONS;;;\n";
    printInitLinkerFields();
    out << ";;;END LINKER INITIALIZATIONS;;;\n\n";

    
    out << "\n\t; allocate global variables\n";

    for(Module::global_iterator i = module->global_begin(),
                                e = module->global_end(); i != e; i++) {
        if(!i->isDeclaration()) {
            const GlobalVariable *g = i;
            const Constant *c = g->getInitializer();
            printSimpleInstruction("aload_0");
            printStartInvocationTag();
            printConstLoad(
                APInt(32, targetData->getTypeAllocSize(c->getType()), false));
            printEndInvocationTag("lljvm/runtime/Memory/allocateData(I)I");
            printSimpleInstruction("putfield",
                classname + "/" + getValueName(g) + " I");
        }
    }
    
    out << "\n\t; initialize global variables\n";
    for(Module::global_iterator i = module->global_begin(),
                                e = module->global_end(); i != e; i++) {
        if(!i->isDeclaration()) {
            const GlobalVariable *g = i;
            const Constant *c = g->getInitializer();
            printSimpleInstruction("aload_0");
            printSimpleInstruction("getfield",
                classname + "/" + getValueName(g) + " I");
            printStaticConstant(c);
            printSimpleInstruction("pop");
            out << '\n';
        }
    }

    out << "\n"
           "\treturn\n"
           ".end method\n\n";
           
           
   out << ".method public destroy(Llljvm/runtime/Context;)V\n";
   printSimpleInstruction("return");
   printSimpleInstruction(".limit stack 0");
   printSimpleInstruction(".limit locals 2");   
   out << ".end method\n\n";

}