[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