[llvm] r199191 - LTO: add API to set strategy for -internalize

Duncan P. N. Exon Smith dexonsmith at apple.com
Tue Jan 14 10:59:13 PST 2014


Reapplied in r199244, this time after a successful check-all.  Sorry for my carelessness!

On Jan 14, 2014, at 7:50 AM, Duncan Exon Smith <dexonsmith at apple.com> wrote:

> Thanks for reverting -- I neglected to run it with the final patch.  I'll have a look.
> 
> -- dpnes
> 
>> On Jan 14, 2014, at 1:46, NAKAMURA Takumi <geek4civic at gmail.com> wrote:
>> 
>> Excuse me, I have reverted it in r199197.
>> Did you run check-llvm?
>> 
>> 2014/1/14 Duncan P. N. Exon Smith <dexonsmith at apple.com>:
>>> Author: dexonsmith
>>> Date: Tue Jan 14 00:37:26 2014
>>> New Revision: 199191
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=199191&view=rev
>>> Log:
>>> LTO: add API to set strategy for -internalize
>>> 
>>> 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=199191&r1=199190&r2=199191&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm-c/lto.h (original)
>>> +++ llvm/trunk/include/llvm-c/lto.h Tue Jan 14 00:37:26 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=199191&r1=199190&r2=199191&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h (original)
>>> +++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h Tue Jan 14 00:37:26 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=199191&r1=199190&r2=199191&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Transforms/IPO.h (original)
>>> +++ llvm/trunk/include/llvm/Transforms/IPO.h Tue Jan 14 00:37:26 2014
>>> @@ -108,14 +108,17 @@ 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);
>>> 
>>> //===----------------------------------------------------------------------===//
>>> /// 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=199191&r1=199190&r2=199191&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
>>> +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Tue Jan 14 00:37:26 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=199191&r1=199190&r2=199191&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/IPO/Internalize.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/IPO/Internalize.cpp Tue Jan 14 00:37:26 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,11 @@ 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) {
>>> -  return new InternalizePass(ExportList);
>>> +ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList,
>>> +                                        bool OnlyHidden) {
>>> +  return new InternalizePass(ExportList, OnlyHidden);
>>> }
>>> 
>>> Modified: llvm/trunk/tools/lto/lto.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=199191&r1=199190&r2=199191&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/tools/lto/lto.cpp (original)
>>> +++ llvm/trunk/tools/lto/lto.cpp Tue Jan 14 00:37:26 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