This is an archive of the discontinued LLVM Phabricator instance.

DIBuilder support DI Macro creation
ClosedPublic

Authored by aaboud on Jan 11 2016, 1:03 PM.

Details

Summary

Added DI macro creation API to DIBuilder.
This API will be used by Clang to create the DIMacro and DIMacroFile metadata entities.

Note: Usage of these new interface functions can be found in D16135.

Diff Detail

Repository
rL LLVM

Event Timeline

aaboud updated this revision to Diff 44537.Jan 11 2016, 1:03 PM
aaboud retitled this revision from to DIBuilder support DI Macro creation.
aaboud updated this object.
aaboud added a subscriber: llvm-commits.
aprantl added inline comments.Jan 11 2016, 1:19 PM
include/llvm/IR/DIBuilder.h
730 ↗(On Diff #44537)

What's an example of a self-referential F?

aaboud updated this revision to Diff 44717.Jan 13 2016, 12:49 AM
aaboud updated this object.

Applied changes according to Adrian comment.

include/llvm/IR/DIBuilder.h
730 ↗(On Diff #44537)

I think there is no such example, it is a copy paste issue.
Thanks for noticing, I will fix the comment and the code.

aprantl edited edge metadata.Jan 13 2016, 9:24 AM

IIRC DIBuilder has a couple of unit tests (unittests/IR/IRBuilderTest.cpp). Could you add tests for the new functionality?

include/llvm/IR/DIBuilder.h
49 ↗(On Diff #44717)

What are the allowed types of parents?

124 ↗(On Diff #44717)

Instead of passing a bool, which leads to call sites like
/* undef */ true
would it make sense to have inline convenience wrappers like "createMacroDefine/Undef" or passing in the DW_MACINFO_undef value directly?

125 ↗(On Diff #44717)

This is usually written as = StringRef()

aaboud updated this revision to Diff 44976.Jan 15 2016, 4:26 AM
aaboud marked 3 inline comments as done.

Added unit test that covers the macro new DIBuilder create API.
Applied more fixes according to Adrian comments.

IIRC DIBuilder has a couple of unit tests (unittests/IR/IRBuilderTest.cpp). Could you add tests for the new functionality?

Done.

include/llvm/IR/DIBuilder.h
49 ↗(On Diff #44717)

Added a comment explaining the types.
I still have to use "Metadata *" as "MDTuple::get()" function expect a vector of "Metadata *"!

124 ↗(On Diff #44717)

Changed the code to pass DW_MACINFO_define and DW_MACINFO_undef.

Just one final question: Why is replaceArrays() necessary? We need it for DICompositeType because composite types may be recursive. Is that also the case for DIMacroNodeArray?

Just one final question: Why is replaceArrays() necessary? We need it for DICompositeType because composite types may be recursive. Is that also the case for DIMacroNodeArray?

The reason why DIMacroFile need the replaceArrays() function is that when we create the DIMacroFile, we still do not have the list of children nodes of that DIE.
So, we create an empty one,,and later, when we finalize the DIBuilder and all Macro DIEs are already created, only then we can fix the children list of the DIMacroFile and replace the empty list with the actual children list.

If I understand your concern well, you are suggesting that instead of the "replaceArrays()" function, we implement a "DIMacroFile::replaceMacros()" similar to the function of the DICompileUnit, correct?

aaboud updated this revision to Diff 65549.Jul 26 2016, 10:26 AM
aaboud added reviewers: erichkeane, bwyma.

Updated patch to top of trunk (r276746) - Thanks to Ranjeet Singh.

Please, provide your feedback.

Yes, I think putting it on DIMacroFile might be a better interface, but I'm not sure.
But then there is also another issue: I'm not sure whether it is legal to modify a uniquable (non-distinct) DINode because it will break uniquing. So I think DIMacroFiles must be created distinct to avoid this problem. Would this cause an issue during LTO with duplication or are they expected to be mostly unique across compile units anyway?

aaboud added a comment.Aug 8 2016, 5:57 AM

Yes, I think putting it on DIMacroFile might be a better interface, but I'm not sure.
But then there is also another issue: I'm not sure whether it is legal to modify a uniquable (non-distinct) DINode because it will break uniquing. So I think DIMacroFiles must be created distinct to avoid this problem. Would this cause an issue during LTO with duplication or are they expected to be mostly unique across compile units anyway?

After short investigation there is an issue with both options.

  1. Defining the Macro Dies as distinct will work from functional aspect, however, it will prevent sharing similar Macro Dies, which will be a real issue in dwarf5, where we can make usage of such sharing.
  2. Defining the Macro Dies as unique will cause a functional issue, though not with the LTO, but with direct compilation like in the following example:

t.h

#ifdef A
#define Y X
#else
#define Y Z
#endif

t1.h

#define A
#include "t.h"
#undef A

t2.h

#define B
#include "t.h"
#undef B

t.c

#include "t1.h"
#include "t2.h"

In this case the LLVM IR for "t.h" will look like this:

!306 = !DIMacroFile(line: 2, file: !307, nodes: !308)
!307 = !DIFile(filename: "t.h", directory: "/")
!308 = !{!309, !310}
!309 = !DIMacro(type: DW_MACINFO_define, line: 2, name: "Y", value: "X")
!310 = !DIMacro(type: DW_MACINFO_define, line: 4, name: "Y", value: "Z")

Even though in this case the include of "t.h" from "t1.h" does not match the include of "t.h" from "t2.h", but because when we created the DIMacroFile we created it with empty nodes, there was a match (same macro tag, same line number, same file name, same empty node list).
The reason why LTO does not have the same problem, is that when we link the IR, the DIMacroFile already have its node list initialized, so the compare will be accurate.

So, if you ask me, I still prefer to use unique on Macro nodes, however we need to create them with the nodes and prevent changing them later.
Need to work on fixing this on the Clang part at D16135.

This doesn't look too bad to me, but maybe I'm not seeing the whole picture: The bulk of the nodes will be DIMacro nodes and if I understand correctly they are leaf nodes and can safely be created non-distinct and shareable immediately. For the DIMacroFiles, we could create them as temporary distinct nodes first — similar to DIBuilder::createReplaceableCompositeType() and then replace them with non-distinct nodes once the lists are finalized.

What's the status of this?

Yes, I think putting it on DIMacroFile might be a better interface, but I'm not sure.
But then there is also another issue: I'm not sure whether it is legal to modify a uniquable (non-distinct) DINode because it will break uniquing. So I think DIMacroFiles must be created distinct to avoid this problem. Would this cause an issue during LTO with duplication or are they expected to be mostly unique across compile units anyway?

What's the status of this?

Sorry, for the delay, I was in an extended vacation.
Following F2F discussion with Richard Smith in the LLVM conference I have now some ideas on how to implement the Macro support in Clang.
So, expect new patches in the comming few weeks.

Again, sorry for the delay.

Regards,
Amjad

No worries, I was mostly concerned that this might have been blocked on waiting for feedback from myself.

aaboud updated this revision to Diff 82695.Dec 29 2016, 2:07 PM

Improved the code based on Adrian's comments.

aprantl added inline comments.Jan 3 2017, 10:50 AM
lib/IR/DIBuilder.cpp
94 ↗(On Diff #82695)

if (!I.first)
Also comment what it means if it is null and why we are continuing?

101 ↗(On Diff #82695)

clang-format?

201 ↗(On Diff #82695)

This comment doesn't really explain anything that isn't obvious from reading the next line. Could be dropped.

210 ↗(On Diff #82695)

Why does this need to be a temporary node? Can there be cycles?

214 ↗(On Diff #82695)

spelling this as AllMacrosPerParent.insert({MF, nullptr}); is perhaps more obvious?

Thanks Adrian for the comments, I will do the changes as needed and upload a new patch.
I have one answer below.

lib/IR/DIBuilder.cpp
210 ↗(On Diff #82695)

The temporary node is needed because at this point we do not know the Elements of the DIMacroFile. So, we cannot create the DIMacroFile as Unique at this point (it is not final yet).

So, there is no Cycles, but temporary nodes are still needed, and it was you who suggested this solution few months ago :)

By the way, 'Elements' will always be an empty array passed to this function, but i was not sure if I should remove it or keep it. What do you think?

aprantl accepted this revision.Jan 3 2017, 11:09 AM
aprantl edited edge metadata.

Thanks! LGTM with outstanding comments addressed.

lib/IR/DIBuilder.cpp
210 ↗(On Diff #82695)

I think we should remove it then and explain how it is being populated in the doxygen comment.

This revision is now accepted and ready to land.Jan 3 2017, 11:09 AM
This revision was automatically updated to reflect the committed changes.
aaboud marked 5 inline comments as done.