[llvm] r199244 - Reapply "LTO: add API to set strategy for -internalize"

Rafael EspĂ­ndola rafael.espindola at gmail.com
Wed Apr 2 07:16:24 PDT 2014


Sorry I missed this the first time. If I understand it correctly, it
exist so that we don't internalize symbols when using ld -r. Why can't
the linker simply list the symbols that should not be internalized in
that case as it does for every other file?


On 14 January 2014 13:52, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
> Author: dexonsmith
> Date: Tue Jan 14 12:52:17 2014
> New Revision: 199244
>
> URL: http://llvm.org/viewvc/llvm-project?rev=199244&view=rev
> Log:
> Reapply "LTO: add API to set strategy for -internalize"
>
> Reapply r199191, reverted in r199197 because it carelessly broke
> Other/link-opts.ll.  The problem was that calling
> createInternalizePass("main") would select
> createInternalizePass(bool("main")) instead of
> createInternalizePass(ArrayRef<const char *>("main")).  This commit
> fixes the bug.
>
> The original commit message follows.
>
> Add API to LTOCodeGenerator to specify a strategy for the -internalize
> pass.
>
> This is a new attempt at Bill's change in r185882, which he reverted in
> r188029 due to problems with the gold linker.  This puts the onus on the
> linker to decide whether (and what) to internalize.
>
> In particular, running internalize before outputting an object file may
> change a 'weak' symbol into an internal one, even though that symbol
> could be needed by an external object file --- e.g., with arclite.
>
> This patch enables three strategies:
>
> - LTO_INTERNALIZE_FULL: the default (and the old behaviour).
> - LTO_INTERNALIZE_NONE: skip -internalize.
> - LTO_INTERNALIZE_HIDDEN: only -internalize symbols with hidden
>   visibility.
>
> LTO_INTERNALIZE_FULL should be used when linking an executable.
>
> Outputting an object file (e.g., via ld -r) is more complicated, and
> depends on whether hidden symbols should be internalized.  E.g., for
> ld -r, LTO_INTERNALIZE_NONE can be used when -keep_private_externs, and
> LTO_INTERNALIZE_HIDDEN can be used otherwise.  However,
> LTO_INTERNALIZE_FULL is inappropriate, since the output object file will
> eventually need to link with others.
>
> lto_codegen_set_internalize_strategy() sets the strategy for subsequent
> calls to lto_codegen_write_merged_modules() and lto_codegen_compile*().
>
> <rdar://problem/14334895>
>
> Modified:
>     llvm/trunk/include/llvm-c/lto.h
>     llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
>     llvm/trunk/include/llvm/Transforms/IPO.h
>     llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
>     llvm/trunk/lib/Transforms/IPO/Internalize.cpp
>     llvm/trunk/tools/lto/lto.cpp
>
> Modified: llvm/trunk/include/llvm-c/lto.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=199244&r1=199243&r2=199244&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm-c/lto.h (original)
> +++ llvm/trunk/include/llvm-c/lto.h Tue Jan 14 12:52:17 2014
> @@ -40,7 +40,7 @@ typedef bool lto_bool_t;
>   * @{
>   */
>
> -#define LTO_API_VERSION 5
> +#define LTO_API_VERSION 6
>
>  typedef enum {
>      LTO_SYMBOL_ALIGNMENT_MASK              = 0x0000001F, /* log2 of alignment */
> @@ -73,6 +73,11 @@ typedef enum {
>      LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC = 2
>  } lto_codegen_model;
>
> +typedef enum {
> +    LTO_INTERNALIZE_FULL   = 0,
> +    LTO_INTERNALIZE_NONE   = 1,
> +    LTO_INTERNALIZE_HIDDEN = 2
> +} lto_internalize_strategy;
>
>  /** opaque reference to a loaded object module */
>  typedef struct LTOModule*         lto_module_t;
> @@ -264,6 +269,14 @@ lto_codegen_set_assembler_args(lto_code_
>                                 int nargs);
>
>  /**
> + * Sets the strategy to use during internalize.  Default strategy is
> + * LTO_INTERNALIZE_FULL.
> + */
> +extern void
> +lto_codegen_set_internalize_strategy(lto_code_gen_t cg,
> +                                     lto_internalize_strategy);
> +
> +/**
>   * Tells LTO optimization passes that this symbol must be preserved
>   * because it is referenced by native code or a command line option.
>   */
>
> Modified: llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h?rev=199244&r1=199243&r2=199244&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h (original)
> +++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h Tue Jan 14 12:52:17 2014
> @@ -70,6 +70,7 @@ struct LTOCodeGenerator {
>    void setTargetOptions(llvm::TargetOptions options);
>    void setDebugInfo(lto_debug_model);
>    void setCodePICModel(lto_codegen_model);
> +  void setInternalizeStrategy(lto_internalize_strategy);
>
>    void setCpu(const char *mCpu) { MCpu = mCpu; }
>
> @@ -114,6 +115,14 @@ struct LTOCodeGenerator {
>                        bool disableGVNLoadPRE,
>                        std::string &errMsg);
>
> +  bool shouldInternalize() const {
> +    return InternalizeStrategy != LTO_INTERNALIZE_NONE;
> +  }
> +
> +  bool shouldOnlyInternalizeHidden() const {
> +    return InternalizeStrategy == LTO_INTERNALIZE_HIDDEN;
> +  }
> +
>  private:
>    void initializeLTOPasses();
>
> @@ -138,6 +147,7 @@ private:
>    bool EmitDwarfDebugInfo;
>    bool ScopeRestrictionsDone;
>    lto_codegen_model CodeModel;
> +  lto_internalize_strategy InternalizeStrategy;
>    StringSet MustPreserveSymbols;
>    StringSet AsmUndefinedRefs;
>    llvm::MemoryBuffer *NativeObjectFile;
>
> Modified: llvm/trunk/include/llvm/Transforms/IPO.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=199244&r1=199243&r2=199244&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/IPO.h (original)
> +++ llvm/trunk/include/llvm/Transforms/IPO.h Tue Jan 14 12:52:17 2014
> @@ -108,14 +108,19 @@ Pass *createPruneEHPass();
>  ////
>  /// The symbols in \p ExportList are never internalized.
>  ///
> +/// When OnlyHidden=true, only symbols with hidden visibility are internalized.
> +///
>  /// The symbol in DSOList are internalized if it is safe to drop them from
>  /// the symbol table.
>  ///
>  /// Note that commandline options that are used with the above function are not
>  /// used now!
> -ModulePass *createInternalizePass(ArrayRef<const char *> ExportList);
> +ModulePass *createInternalizePass(ArrayRef<const char *> ExportList,
> +                                  bool OnlyHidden = false);
>  /// createInternalizePass - Same as above, but with an empty exportList.
> -ModulePass *createInternalizePass();
> +ModulePass *createInternalizePass(bool OnlyHidden = false);
> +/// createInternalizePass - Resolve ambiguity when passed a const char *.
> +ModulePass *createInternalizePass(const char *SingleExport);
>
>  //===----------------------------------------------------------------------===//
>  /// createDeadArgEliminationPass - This pass removes arguments from functions
>
> Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=199244&r1=199243&r2=199244&view=diff
> ==============================================================================
> --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
> +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Tue Jan 14 12:52:17 2014
> @@ -62,7 +62,8 @@ const char* LTOCodeGenerator::getVersion
>  LTOCodeGenerator::LTOCodeGenerator()
>      : Context(getGlobalContext()), Linker(new Module("ld-temp.o", Context)),
>        TargetMach(NULL), EmitDwarfDebugInfo(false), ScopeRestrictionsDone(false),
> -      CodeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), NativeObjectFile(NULL) {
> +      CodeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
> +      InternalizeStrategy(LTO_INTERNALIZE_FULL), NativeObjectFile(NULL) {
>    initializeLTOPasses();
>  }
>
> @@ -164,6 +165,18 @@ void LTOCodeGenerator::setCodePICModel(l
>    llvm_unreachable("Unknown PIC model!");
>  }
>
> +void
> +LTOCodeGenerator::setInternalizeStrategy(lto_internalize_strategy Strategy) {
> +  switch (Strategy) {
> +  case LTO_INTERNALIZE_FULL:
> +  case LTO_INTERNALIZE_NONE:
> +  case LTO_INTERNALIZE_HIDDEN:
> +    InternalizeStrategy = Strategy;
> +    return;
> +  }
> +  llvm_unreachable("Unknown internalize strategy!");
> +}
> +
>  bool LTOCodeGenerator::writeMergedModules(const char *path,
>                                            std::string &errMsg) {
>    if (!determineTarget(errMsg))
> @@ -377,7 +390,7 @@ static void accumulateAndSortLibcalls(st
>  }
>
>  void LTOCodeGenerator::applyScopeRestrictions() {
> -  if (ScopeRestrictionsDone)
> +  if (ScopeRestrictionsDone || !shouldInternalize())
>      return;
>    Module *mergedModule = Linker.getModule();
>
> @@ -429,7 +442,8 @@ void LTOCodeGenerator::applyScopeRestric
>      LLVMCompilerUsed->setSection("llvm.metadata");
>    }
>
> -  passes.add(createInternalizePass(MustPreserveList));
> +  passes.add(
> +      createInternalizePass(MustPreserveList, shouldOnlyInternalizeHidden()));
>
>    // apply scope restrictions
>    passes.run(*mergedModule);
>
> Modified: llvm/trunk/lib/Transforms/IPO/Internalize.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Internalize.cpp?rev=199244&r1=199243&r2=199244&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/Internalize.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/Internalize.cpp Tue Jan 14 12:52:17 2014
> @@ -54,10 +54,11 @@ APIList("internalize-public-api-list", c
>  namespace {
>    class InternalizePass : public ModulePass {
>      std::set<std::string> ExternalNames;
> +    bool OnlyHidden;
>    public:
>      static char ID; // Pass identification, replacement for typeid
> -    explicit InternalizePass();
> -    explicit InternalizePass(ArrayRef<const char *> ExportList);
> +    explicit InternalizePass(bool OnlyHidden = false);
> +    explicit InternalizePass(ArrayRef<const char *> ExportList, bool OnlyHidden);
>      void LoadFile(const char *Filename);
>      virtual bool runOnModule(Module &M);
>
> @@ -72,16 +73,17 @@ char InternalizePass::ID = 0;
>  INITIALIZE_PASS(InternalizePass, "internalize",
>                  "Internalize Global Symbols", false, false)
>
> -InternalizePass::InternalizePass()
> -  : ModulePass(ID) {
> +InternalizePass::InternalizePass(bool OnlyHidden)
> +  : ModulePass(ID), OnlyHidden(OnlyHidden) {
>    initializeInternalizePassPass(*PassRegistry::getPassRegistry());
>    if (!APIFile.empty())           // If a filename is specified, use it.
>      LoadFile(APIFile.c_str());
>    ExternalNames.insert(APIList.begin(), APIList.end());
>  }
>
> -InternalizePass::InternalizePass(ArrayRef<const char *> ExportList)
> -  : ModulePass(ID){
> +InternalizePass::InternalizePass(ArrayRef<const char *> ExportList,
> +                                 bool OnlyHidden)
> +  : ModulePass(ID), OnlyHidden(OnlyHidden) {
>    initializeInternalizePassPass(*PassRegistry::getPassRegistry());
>    for(ArrayRef<const char *>::const_iterator itr = ExportList.begin();
>          itr != ExportList.end(); itr++) {
> @@ -106,7 +108,11 @@ void InternalizePass::LoadFile(const cha
>  }
>
>  static bool shouldInternalize(const GlobalValue &GV,
> -                              const std::set<std::string> &ExternalNames) {
> +                              const std::set<std::string> &ExternalNames,
> +                              bool OnlyHidden) {
> +  if (OnlyHidden && !GV.hasHiddenVisibility())
> +    return false;
> +
>    // Function must be defined here
>    if (GV.isDeclaration())
>      return false;
> @@ -155,9 +161,8 @@ bool InternalizePass::runOnModule(Module
>    }
>
>    // 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 (!shouldInternalize(*I, ExternalNames))
> +    if (!shouldInternalize(*I, ExternalNames, OnlyHidden))
>        continue;
>
>      I->setLinkage(GlobalValue::InternalLinkage);
> @@ -191,10 +196,9 @@ bool InternalizePass::runOnModule(Module
>
>    // 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 (!shouldInternalize(*I, ExternalNames))
> +    if (!shouldInternalize(*I, ExternalNames, OnlyHidden))
>        continue;
>
>      I->setLinkage(GlobalValue::InternalLinkage);
> @@ -206,7 +210,7 @@ bool InternalizePass::runOnModule(Module
>    // 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 (!shouldInternalize(*I, ExternalNames))
> +    if (!shouldInternalize(*I, ExternalNames, OnlyHidden))
>        continue;
>
>      I->setLinkage(GlobalValue::InternalLinkage);
> @@ -218,10 +222,15 @@ bool InternalizePass::runOnModule(Module
>    return Changed;
>  }
>
> -ModulePass *llvm::createInternalizePass() {
> -  return new InternalizePass();
> +ModulePass *llvm::createInternalizePass(bool OnlyHidden) {
> +  return new InternalizePass(OnlyHidden);
> +}
> +
> +ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList,
> +                                        bool OnlyHidden) {
> +  return new InternalizePass(ExportList, OnlyHidden);
>  }
>
> -ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList) {
> -  return new InternalizePass(ExportList);
> +ModulePass *llvm::createInternalizePass(const char *SingleExport) {
> +  return createInternalizePass(ArrayRef<const char *>(SingleExport));
>  }
>
> Modified: llvm/trunk/tools/lto/lto.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=199244&r1=199243&r2=199244&view=diff
> ==============================================================================
> --- llvm/trunk/tools/lto/lto.cpp (original)
> +++ llvm/trunk/tools/lto/lto.cpp Tue Jan 14 12:52:17 2014
> @@ -252,6 +252,13 @@ void lto_codegen_set_assembler_args(lto_
>    // In here only for backwards compatibility. We use MC now.
>  }
>
> +/// lto_codegen_set_internalize_strategy - Sets the strategy to use during
> +/// internalize.
> +void lto_codegen_set_internalize_strategy(lto_code_gen_t cg,
> +                                          lto_internalize_strategy strategy) {
> +  cg->setInternalizeStrategy(strategy);
> +}
> +
>  /// lto_codegen_add_must_preserve_symbol - Adds to a list of all global symbols
>  /// that must exist in the final generated code. If a function is not listed
>  /// there, it might be inlined into every usage and optimized away.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list