This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Refactoring DIType::setFlags to DIType::cloneWithFlags
ClosedPublic

Authored by rtereshin on May 31 2018, 6:51 PM.

Details

Summary

and using the latter in DIBuilder::createArtificialType and
DIBuilder::createObjectPointerType methods as well as introducing
mirroring DISubprogram::cloneWithFlags and
DIBuilder::createArtificialSubprogram methods.

The primary goal here is to add createArtificialSubprogram to support
a pass downstream while keeping the method consistent with the
existing ones and making sure we don't encourage changing already
created DI-nodes.

Diff Detail

Repository
rL LLVM

Event Timeline

rtereshin created this revision.May 31 2018, 6:51 PM

We generally try to discourage modifying MDNodes after creation since this is an inherently dangerous thing to do since you never know who might be holding on to a pointer to an MDNode. Do you have really good reason to alter the flags on an existing node, or could you also just set the flags correctly at creation time? Even if the answer is yes I wonder if it wouldn't be better to clone a new distinct node with the modified flag.

We generally try to discourage modifying MDNodes after creation since this is an inherently dangerous thing to do since you never know who might be holding on to a pointer to an MDNode. Do you have really good reason to alter the flags on an existing node, or could you also just set the flags correctly at creation time? Even if the answer is yes I wonder if it wouldn't be better to clone a new distinct node with the modified flag.

I'm cloning an existing node to a temporary node, modifying the flags, and converting it to a distinct node.

Do you want me to put all of it in a single method instead of providing a method for modifying the flags?
If so, do we need to change DIType the same way? Currently it has public setFlags method, which is apparently only used by DIBuilder's methods that clone - set flags - convert to a distinct node.

I didn't realize the DIBuilder was using the same workflow in createTypeWithFlags(). What do you think about making this method private and only having DIBuilder call it in a controlled setting (and add a DIBuilder createSubprogramWithFlags() method)?

I didn't realize the DIBuilder was using the same workflow in createTypeWithFlags(). What do you think about making this method private and only having DIBuilder call it in a controlled setting (and add a DIBuilder createSubprogramWithFlags() method)?

That would require making DIBuilder a friend to DIType and DISubprogram. And looks like none of the DI* classes have DIBuilder as a friend at the moment, not sure I want to start the tradition.

Alternatively, we could:

  1. toughen the assertion to isTemporary instead of just !isUniqued and mirror the methods for DISubprogram, or
  2. remove setFlags methods entirely and replace them with cloneWithFlags on DIType / DISubprogram directly, having DIBuilder just call it and replaceWithDistinct later, or
  3. same as 2, but have cloneWithFlags returning already distinct node and remove createTypeWithFlags from DIBuilder (which is private anyway by the virtue of being a static function) and add DIBuilder::createArtificialSubprogram (similar to DIBuilder::createArtificialType)
aprantl added a comment.EditedJun 1 2018, 10:57 AM

toughen the assertion to isTemporary instead of just !isUniqued and mirror the methods for DISubprogram, or

I like that.

Options 2 and 3 also work for me. It's more work to implement but it seems even cleaner.

rtereshin updated this revision to Diff 149547.Jun 1 2018, 2:24 PM
rtereshin retitled this revision from [DebugInfo] Adding DISubprogram::setFlags identical to DIType::setFlags to [DebugInfo] Refactoring DIType::setFlags to DIType::cloneWithFlags.
rtereshin edited the summary of this revision. (Show Details)

making sure we don't expose setters on already created DI nodes + adding a test

aprantl accepted this revision.Jun 1 2018, 2:39 PM

Looks good. I have a few nitpicks about the doxygen comments inline, but otherwise this is good to go!

include/llvm/IR/DIBuilder.h
518 ↗(On Diff #149547)

Create a distinct clone of SP with DIFlagArtificial set. ?

521 ↗(On Diff #149547)

Create a uniqued clone of Ty with DIFlagArtificial set.

524 ↗(On Diff #149547)

etc.

This revision is now accepted and ready to land.Jun 1 2018, 2:39 PM

Oh.. please be sure to update any LLVM clients of the API (such as clang and the LLVM C and Go bindings)

Oh.. please be sure to update any LLVM clients of the API (such as clang and the LLVM C and Go bindings)

If ninja-all passes with clang checked out - does that mean they are all right or I need to explicitly look elsewhere?

rtereshin marked 3 inline comments as done.Jun 1 2018, 2:57 PM

No that seems fine. The bots will tell you if it wasn't enough anyway ;-)

You can do a git grep for the API just to make sure that the Go bindings don't use it, because you probably didn't build them.

This revision was automatically updated to reflect the committed changes.