[LLVMdev] [RFC] Removing static initializers for command line options

Pete Cooper peter_cooper at apple.com
Wed Aug 20 09:31:12 PDT 2014


> On Aug 20, 2014, at 9:15 AM, Pete Cooper <peter_cooper at apple.com> wrote:
> 
> 
>> On Aug 20, 2014, at 8:51 AM, Rafael Espíndola <rafael.espindola at gmail.com> wrote:
>> 
>>> FWIW, I largely agree with Rafael's position here, at least in the near
>>> term.
>>> 
>>> The nice thing about it is that even if we don't stay there forever, it is a
>>> nice incremental improvement over the current state of the world, and we can
>>> actually be mindful going forward of whether the restriction it imposes (an
>>> inability to use "internal" knobs from within a library context that have
>>> multiple different library users in a single address space) proves to be a
>>> significant on-going burden.
>>> 
>>> I actually disagree with this for two reasons.
>>> 
>>> The first is that if there are going to be changes to the code anyway to
>>> remove static initializers, and we can move the storage to the pass at the
>>> same time, the we should make just one change and not two.
>>> 
>>> The second reason is that in most cases these knobs should not be globals.
>>> If I had a piece of data (not a CL::opt) in global scope, only used by one
>>> pass, then I'm sure people would question why it's a global at all and move
>>> it inside the class. We're treating cl::opt as special here when there's no
>>> reason for the opt or the storage to be global.
>>> 
>>> We frown upon the use of globals, otherwise LLVM would be littered with them
>>> like many other C++ code bases. I don't think cl::opts should be special at
>>> all in this respect.
>> 
>> 
>> Note that the call
>> 
>> cl::OptionRegistry::CreateOption<bool>(&ScalarizeLoadStore,
>> "ScalarizeLoadStore",
>>  "scalarize-load-store", cl::Hidden, cl::init(false),
>>  cl::desc("Allow the scalarizer pass to scalarize loads and store"));
>> 
>> ScalarizeLoadStore can actually be a member variable as long as caller
>> guarantees it is still around when the command line is parsed. I have
>> no objections to doing this move in the first pass if you want to.
>> 
>> What I would really like to avoid for now is the
>> 
>> cl::OptionRegistry::GetValue<bool>("ScalarizeLoadStore”);
> Ah, I totally see what you mean now.  Sorry if i had been confused before.
> 
> To be honest, I had exactly the same reservations myself, but then i looked in to how we initialize and create passes and there actually isn’t a nice way to do this right now.
> 
> The trouble is that INITIALIZE_PASS doesn’t actually construct a pass.  It actually constructs a PassInfo which has a pointer to the default constructor of the pass.  Later, if the pass manager needs to (say -scalarize was on the commandline), it will get the default constructor from PassInfo and construct the pass.
> 
> Unfortunately, this completely detaches the lifetime of the pass instance where we want to store the ScalarizeLoadStore bool, from the option code to hook in to the cl::opt stuff.  I originally wanted to do something gross like pass __offset_of(Scalarizer::ScalarizeLoadStore) to the PassInfo and hide the initialization of the option in there.  But that doesn’t work either, as there’s no guarantee you’ll even create a instance of Scalarizer, even though you could pass -scalarize-load-store to the command line.
> 
> So, we do have 2 solutions: a global variable, and a call to GetValue.  As you can see, either way isn’t perfect, but if you can think of another solution i’m sure we can discuss it.
> 
This is very raw, so excuse any mistakes in the code, but I think i came up with a third option.

What if we added a static method to the Scalarizer class.  This method takes pointers to each option storage.  If a pointer is null, the function is being called from INITIALIZE_PASS and so we create all the options.  If a pointer is not null, we’re being called from the pass constructor and we set the value of that option.  I think it would look something like this (which can of course be tidied up).

  static void addOptions(bool *ScalarizeLoadStore = nullptr) {
    Option::iterator ScalarizeLoadStoreOpt =
      getOrAddOption<bool>("scalarize-load-store");
    if (ScalarizeLoadStore) {
      // Get the value of the option.
      *ScalarizeLoadStore = ScalarizeLoadStoreOpt.getValue();
    } else {
      // Adding the option with this name.  Set up its properties.
      ScalarizeLoadStoreOpt.init(cl::Hidden, cl::init(false),
                                 cl::desc("Allow the scalarizer pass to scalarize loads and store"));
    }
  }

Pete
> Thanks,
> Pete
>> 
>> Cheers,
>> Rafael
> 
> 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev





More information about the llvm-dev mailing list