How to get the data dependency information from llvm IR? - c++

For example, the code below
%div = sdiv i32 %add, %36
%38 = trunc i64 %indvars.iv.next18 to i32
%mul11 = mul nsw i32 %div, %38
The fist and third instruction may be a data dependency because the first instruction computes %div and the third one need %div.
Similarly, %38 computed at second instruction, and the third instruction needs it.
Are there any tools or llvm opt commands can get the information about data dependency?
I tried opt -enable-new-pm=0 -da -stats source_ir.ll but nothing will print out.

Related

Why is the final return value of j 10, how does LLVM know it

i have this code:
int main() {
int i = 0;
int &j = i;
j = 10;
return i;
}
and after pass -mem2reg, get the ir as follows:
define dso_local i32 #main() #0 !dbg !7 {
entry:
call void #llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !12
call void #llvm.dbg.value(metadata i32* undef, metadata !13, metadata !DIExpression()), !dbg !12
call void #llvm.dbg.value(metadata i32 10, metadata !11, metadata !DIExpression()), !dbg !12
ret i32 10, !dbg !15
}
What I'm confused about is what analysis LLVM uses to get i and j to be equivalent.
I got the details of this pass runtime:
[2021-12-02 11:53:05.295018000] 0x5626d58d2a20 Executing Pass 'Function Pass Manager' on Module '/usr/local/LLVM/test/e0.ll'...
[2021-12-02 11:53:05.295137300] 0x5626d58bf890 Executing Pass 'Dominator Tree Construction' on Function 'main'...
[2021-12-02 11:53:05.295169500] 0x5626d58bf890 Executing Pass 'Promote Memory to Register' on Function 'main'...
0x5626d58bf330 Required Analyses: Assumption Cache Tracker, Dominator Tree Construction
[2021-12-02 11:53:05.295364900] 0x5626d58bf890 Made Modification 'Promote Memory to Register' on Function 'main'...
0x5626d58bf330 Preserved Analyses: Natural Loop Information, Lazy Branch Probability Analysis, Lazy Block Frequency Analysis, Interval Partition Construction, Post-Dominator Tree Construction, Machine Dominance Frontier Construction, MachineDominator Tree Construction, WebAssembly Exception Information, Spill Code Placement Analysis, Bundle Machine CFG Edges, Machine Natural Loop Construction, Detect single entry single exit regions, Dominance Frontier Construction, View regions of function, Print regions of function to 'dot' file, View regions of function (with no function bodies), MachinePostDominator Tree Construction, Delinearization, Print regions of function to 'dot' file (with no function bodies), Detect single entry single exit regions, Dependence Analysis, Dominator Tree Construction, Dominator Info Printer, Print a call graph, Lazy Machine Block Frequency Analysis, Analysis if a function is memory bound, Strip gc.relocates inserted through RewriteStatepointsForGC, Machine Block Frequency Analysis, Block Frequency Analysis, Basic Alias Analysis (stateless AA impl)
-*- 'Promote Memory to Register' is the last user of following pass instances. Free these instances
[2021-12-02 11:53:05.295628600] 0x5626d58bf890 Freeing Pass 'Dominator Tree Construction' on Function 'main'...
[2021-12-02 11:53:05.295648400] 0x5626d58bf890 Freeing Pass 'Promote Memory to Register' on Function 'main'...
[2021-12-02 11:53:05.295663100] 0x5626d58bf890 Executing Pass 'Module Verifier' on Function 'main'...
-*- 'Module Verifier' is the last user of following pass instances. Free these instances
[2021-12-02 11:53:05.295725200] 0x5626d58bf890 Freeing Pass 'Module Verifier' on Function 'main'...
[2021-12-02 11:53:05.295740400] 0x5626d58d2a20 Made Modification 'Function Pass Manager' on Module '/usr/local/LLVM/test/e0.ll'...
-*- 'Function Pass Manager' is the last user of following pass instances. Free these instances
[2021-12-02 11:53:05.295828100] 0x5626d58d2a20 Freeing Pass 'Assumption Cache Tracker' on Module '/usr/local/LLVM/test/e0.ll'...
[2021-12-02 11:53:05.295850400] 0x5626d58d2a20 Executing Pass 'Print Module IR' on Module '/usr/local/LLVM/test/e0.ll'...
-*- 'Print Module IR' is the last user of following pass instances. Free these instances
[2021-12-02 11:53:05.299496500] 0x5626d58d2a20 Freeing Pass 'Print Module IR' on Module '/usr/local/LLVM/test/e0.ll'...
Can someone help me figure out which analysis or optimization lets LLVM know that i and j are equivalent,very thankful!
Generate unoptimized IR with clang
clang -S -emit-llvm -Xclang -disable-O0-optnone xx.cpp
Optimize the resulting IR with opt
opt --print-after-all -O3 xx.ll -S -o yy.ll
If you look at the IR as it gets optimized you'll see it gets simplified in the SimplifyCFGPass.

ARM Cortex-M HardFault exception on writting halfword to flash using C++

I've written a project using C++ to run on ARM Cortex-M (STM32F0) but I had some problems with accessing defined buffers as class members though I resolved that by defining them as global vars.
But now I'm completely stuck with this new problem which I don't know what to do with it.
I've a code to unlock flash and write something into it and close it. If I implement it in C file and run it through C nature (call from main.c) it works perfect. but calling that through C++ files (whether written inside C or C++ source file) it will throw a HardFault Exception.
static uint32_t waitForLastOperation(uint32_t msDelay)
{
while (READ_BIT(FLASH->SR, FLASH_SR_BSY) && msDelay)
{
LL_mDelay(1);
msDelay--;
}
/* Check FLASH End of Operation flag */
if (READ_BIT((FLASH->SR), (FLASH_SR_EOP)))
{
/* Clear FLASH End of Operation pending bit */
(FLASH->SR) = (FLASH_SR_EOP);
}
if (READ_BIT((FLASH->SR),
(FLASH_SR_WRPERR)) || READ_BIT((FLASH->SR), (FLASH_SR_PGERR)))
{
FLASH->SR = 0U;
return 0;
}
/* There is no error flag set */
return 1;
}
uint32_t programHalfWord(uint16_t data, uint32_t address)
{
uint32_t status;
/* Proceed to program the new data */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Write data in the address */
*(__IO uint16_t*) address = data;
/* Wait for last operation to be completed */
status = waitForLastOperation(FLASH_TIMEOUT);
if (READ_BIT(FLASH->SR, FLASH_SR_EOP))
FLASH->SR = FLASH_SR_EOP;
/* If the program operation is completed, disable the PG Bit */
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
return status;
}
uint32_t flash_unlock()
{
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) == RESET)
return 1;
/* Authorize the FLASH Registers access */
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
/* Verify Flash is unlocked */
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
return 0;
return 1;
}
and this is how I use it:
if(flash_unlock())
{
programHalfWord(0x11, 0x8007C00);
}
It throws exception right after executing *(__IO uint16_t*) address = data;.
Flash is erased at this address, address is aligned (it's actually start of a sector). I've checked everything to make sure that flash is unlocked but it seems that there's something with the code compiled in C++.
I'm using arm-none-eabi-gcc and arm-none-eabi-g++ to compile my code.
Thanks in advance
Update:
Here's the list of flags being used with g++ compiler:
-mcpu=cortex-m0 -std=gnu++14 -g3 -DSTM32F030x6 -DHSE_STARTUP_TIMEOUT=100 -DLSE_STARTUP_TIMEOUT=5000 -DDEBUG -DLSE_VALUE=32768 -DDATA_CACHE_ENABLE=0 -DINSTRUCTION_CACHE_ENABLE=0 -DVDD_VALUE=3300 -DLSI_VALUE=40000 -DHSI_VALUE=8000000 -DUSE_FULL_LL_DRIVER -DPREFETCH_ENABLE=1 -DHSE_VALUE=2000000 -c -I../app/Inc -I../Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I../app/Driver -Og -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-use-cxa-atexit -Wall -fno-short-enums -fstack-usage --specs=nano.specs -mfloat-abi=soft -mthumb
And this is for gcc:
-mcpu=cortex-m0 -std=gnu11 -g3 -DSTM32F030x6 -DHSE_STARTUP_TIMEOUT=100 -DLSE_STARTUP_TIMEOUT=5000 -DDEBUG -DLSE_VALUE=32768 -DDATA_CACHE_ENABLE=0 -DINSTRUCTION_CACHE_ENABLE=0 -DVDD_VALUE=3300 -DLSI_VALUE=40000 -DHSI_VALUE=8000000 -DUSE_FULL_LL_DRIVER -DPREFETCH_ENABLE=1 -DHSE_VALUE=2000000 -c -I../app/Inc -I../Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I../app/Driver -Og -ffunction-sections -fdata-sections -Wall -fno-short-enums -fstack-usage --specs=nano.specs -mfloat-abi=soft -mthumb
and g++ linker:
-mcpu=cortex-m0 -T"./STM32F030K6TX_FLASH.ld" -Wl,-Map="${ProjName}.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
Since it is difficult to analyze the issue without having access to your hardware / software setup, I can only make wild guesses and provide some hints, after having some troubles with STM32 flash programming as well recently (on a different STM32 model (STM32F215RET6)). - But I'm not an expert in this area at all, and I've only used the vendor supplied HAL driver to access the internal flash so far.
The error might be caused by a memory bus error.
It would be interesting to verify if that's case with a debugger (e.g. by reading the flash status register (FLASH_SR), right after the error occurred).
The question is: Why does your C code work, when compiled with gcc and why not, when compiled with g++? I guess, it might have something to do with a technical detail, that the compiler "doesn't know" about the underlying restrictions of the architecture / memory model.
The STM32F030K6T reference manual (RM0360) says, in section "3.2.2 Flash program and erase operations, Main Flash memory programming":
The main Flash memory can be programmed 16 bits at a time. The program operation is started when the CPU writes a half-word into a main Flash memory address with the PG bit of the FLASH_CR register set. Any attempt to write data that are not half-word long will result in a bus error generating a Hard Fault interrupt.
So, 32-bit write access to the internal flash will cause a Hard Fault interrupt.
When you compile the project with assembly listing generation enabled, you could analyze what's exactly going in your C++ variant, and compare it to the generated machine code of the C variant.
Since I've been working on a STM32 flash related issue recently as well, I've looked up what's going on in the vendor supplied flash code in my case (stm32f2xx_hal_flash.c), and it turns out, that the main write operation to the flash (*(__IO uint16_t*)Address = Data;) is translated to the matching ARM half-word store instruction strh, like expected:
strh r1, [r0]
This could be verified by looking at the auto-generated assembly listings for the ST supplied FLASH_Program_HalfWord() function in stm32f2xx_hal_flash.c. It looks like that (compiled with GCC with no optimization and debugging information -Og):
662:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
663:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** {
140 .loc 1 663 1 is_stmt 1 view -0
141 .cfi_startproc
142 # args = 0, pretend = 0, frame = 0
143 # frame_needed = 0, uses_anonymous_args = 0
144 # link register save eliminated.
664:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** /* Check the parameters */
665:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** assert_param(IS_FLASH_ADDRESS(Address));
145 .loc 1 665 3 view .LVU27
666:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c ****
667:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** /* If the previous operation is completed, proceed to program the new data */
668:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
146 .loc 1 668 3 view .LVU28
147 0000 074B ldr r3, .L9
148 0002 1A69 ldr r2, [r3, #16]
149 0004 22F44072 bic r2, r2, #768
150 0008 1A61 str r2, [r3, #16]
669:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** FLASH->CR |= FLASH_PSIZE_HALF_WORD;
151 .loc 1 669 3 view .LVU29
152 .loc 1 669 13 is_stmt 0 view .LVU30
153 000a 1A69 ldr r2, [r3, #16]
154 000c 42F48072 orr r2, r2, #256
155 0010 1A61 str r2, [r3, #16]
670:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** FLASH->CR |= FLASH_CR_PG;
156 .loc 1 670 3 is_stmt 1 view .LVU31
157 .loc 1 670 13 is_stmt 0 view .LVU32
158 0012 1A69 ldr r2, [r3, #16]
159 0014 42F00102 orr r2, r2, #1
160 0018 1A61 str r2, [r3, #16]
671:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c ****
672:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** *(__IO uint16_t*)Address = Data;
161 .loc 1 672 3 is_stmt 1 view .LVU33
162 .loc 1 672 28 is_stmt 0 view .LVU34
163 001a 0180 strh r1, [r0] # movhi
673:Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_flash.c **** }
164 .loc 1 673 1 view .LVU35
165 001c 7047 bx lr
166 .L10:
167 001e 00BF .align 2
168 .L9:
169 0020 003C0240 .word 1073888256
170 .cfi_endproc
The generated machine code could be disassembled and inspected with objdump, without all the annotations, like that:
$ arm-none-eabi-objdump -d -j .text.FLASH_Program_HalfWord build/stm32f2xx_hal_flash.o
build/stm32f2xx_hal_flash.o: file format elf32-littlearm
Disassembly of section .text.FLASH_Program_HalfWord:
00000000 <FLASH_Program_HalfWord>:
0: 4b07 ldr r3, [pc, #28] ; (20 <FLASH_Program_HalfWord+0x20>)
2: 691a ldr r2, [r3, #16]
4: f422 7240 bic.w r2, r2, #768 ; 0x300
8: 611a str r2, [r3, #16]
a: 691a ldr r2, [r3, #16]
c: f442 7280 orr.w r2, r2, #256 ; 0x100
10: 611a str r2, [r3, #16]
12: 691a ldr r2, [r3, #16]
14: f042 0201 orr.w r2, r2, #1
18: 611a str r2, [r3, #16]
1a: 8001 strh r1, [r0, #0]
1c: 4770 bx lr
1e: bf00 nop
20: 40023c00 .word 0x40023c00
It would be interesting, if you could find out how it looks like in your object file compiled as C++. Is it also using the strh instruction?
By the way, all the ARM instructions are documented also be ST in the STM32F0xxx Cortex-M0 programming manual (PM0215):
The Cortex-M0 processor implements the ARMv6-M architecture, which is based on the 16-bit Thumb® instruction set and includes Thumb-2 technology.
STRHRt, [Rn, <Rm|#imm>] Store register as halfword
And as a reference, also in the ARM®v6-M Architecture Reference Manual of course.
Side note 1:
The reference manual says that address 0x8007C00 is right at the beginning of flash page 31, in flash sector 7, assuming a STM32F030K6Tx chip is used:
Forgetting about this could cause issues, if the sector is write protected via flash option bytes (but that obviously wasn't the case, since it works fine in the C variant). Just for the sake of completeness (you've already commented on that), a quote from the reference manual, "4.1.3 Write protection option byte":
This set of registers is used to write-protect the Flash memory.
Clearing a bit in WRPx field (and at the same time setting a
corresponding bit in nWRPx field) will write-protect the given memory
sector. For STM32F030x4, STM32F030x6, STM32F070x6, STM32F030x8 and
STM32F070xB devices, WRP bits from 0 to 31 are protecting the
Flash memory by sector of 4 kB.
(Possibly unrelated, but also worth mentioning: beware of the different conditions present when Read Protection (RDP) Level 2 or Level 3 is active. RDP is a different protection mechanism, separate from the sector protection via flash option bytes, or lock state of the flash. Reading the flash from a debugger or when executing form RAM will cause a Hard Fault when RDP Level 2 or 3 is used. Documented in the reference manual, section "3.3.1 Read protection".)
Side note 2:
You could try to mix the official HAL C driver code or your own tested flash related C code, and the new C++ parts of the project, and check if the problem still occurs.
(Be careful when mixing C and C++, and always take care of naming mangeling by using extern "C" { ... }, related post: https://stackoverflow.com/a/1041880/5872574)
Side note 3:
Like already mentioned, I've recently had an unrelated issue with flash programming as well. And saw strange bus errors (in the status register after a Hard Fault). I also made sure that the flash was unlocked, and not write protected. If I remember correctly, I had to add this in front of my erase / write operations (but I do not remember exactly and can't find it right now). It was a necessary but strange fix, because there was no operation in progress, besides regular program execution (from flash).
while (FLASH_WaitForLastOperation(100) != HAL_OK) {
HAL_IWDG_Refresh(&hiwdg);
}
This issue possibly had something to do with the way the STM32 uses the flash with a prefetch buffer / wait states / instruction cache and the data cache like described in the reference manual (see also: FLASH_ACR register). I didn't investigate the issue any further. Just make sure that there is no flash operation pending/active when a write/erase access is initiated.
Also interesting to note, program/erase operations will prevent any read access to the bus (flash memory), but they will not cause an error, like described in the reference manual, in section "3.2.2 Flash program and erase operations":
An ongoing Flash memory operation will not block the CPU as long as
the CPU does not access the Flash memory.
On the contrary, during a program/erase operation to the Flash memory,
any attempt to read the Flash memory will stall the bus. The read
operation will proceed correctly once the program/erase operation has
completed. This means that code or data fetches cannot be made while a
program/erase operation is ongoing.
For program and erase operations on the Flash memory (write/erase),
the internal RC oscillator (HSI) must be ON.
EDIT:
In order to check whether there's really enough flash memory left to write to, and that the area is really unused by the running binary itself, these commands could come in handy, meant as a future reference (using my test binary for an STM32F215RET here):
$ arm-none-eabi-strip build/prj.elf
$ arm-none-eabi-objdump -h build/prj.elf
build/prj.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .isr_vector 00000184 08000000 08000000 00010000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 000134a0 08000188 08000188 00010188 2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00002968 08013628 08013628 00023628 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .ARM 00000008 08015f90 08015f90 00025f90 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .init_array 00000004 08015f98 08015f98 00025f98 2**2
CONTENTS, ALLOC, LOAD, DATA
5 .fini_array 00000004 08015f9c 08015f9c 00025f9c 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .data 000002c0 20000000 08015fa0 00030000 2**3
CONTENTS, ALLOC, LOAD, DATA
7 .bss 0000149c 200002c0 08016260 000302c0 2**3
ALLOC
8 ._user_heap_stack 00000604 2000175c 08016260 0003175c 2**0
ALLOC
9 .ARM.attributes 00000029 00000000 00000000 000302c0 2**0
CONTENTS, READONLY
10 .comment 0000001e 00000000 00000000 000302e9 2**0
CONTENTS, READONLY
0x08016260 marks the end of the used flash memory by the binary.
That can be verified with arm-none-eabi-size:
$ arm-none-eabi-size build/prj.elf
text data bss dec hex filename
90004 712 6816 97532 17cfc build/prj.elf
$ echo $((90004 + 712))
90716
$ echo $((0x08016260 - 0x08000000 - (90004 + 712)))
4
So, with 2**3 -> 8 byte alignment and a flash base address of 0x08000000, that means that 90720 bytes of flash memory are actually used by the binary.
To find out which of the flash sectors are left unused, it is now easy to look the address up directly in the "Flash memory organization" table in the reference manual.
In my case, the linker script was modified to make sure that only half of the flash is used, like that:
$ cat STM32F215RETx_FLASH.ld
(...)
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 256K /* keep 256K free at the end */
/* FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K */
}
(...)
That way you'll get a linker error if the binary gets too large.
I had the same issue. My mistake was invalid alignment.
I'm assured 90% of such a errors is alignment issues, especially on Cortex-M0.
I've made proper alignment of my strucrure inside C++ class and it was enough.
Note: functions executed in RAM, like write half page, should better be inside extern "C" {} expression.

How to get lli execution trace

Is there any way to get an lli execution trace. As an example for a given program:
define dso_local i32 #main() {
%1 = alloca i32, align 4
store i32 1, i32* %1, align 4
%2 = load i32, i32* %1, align 4
ret i32 %2
}
I would like to have some runtime output like:
$ lli test.ll -trace
%1 = alloca(4)
st %1, 1 ; [%1] = 1
ld %1 -> %2 ; %2 = 1
ret %2 ; ret 1
I've found an XRay project but it seems to be complicated. Are there any llc native ways to output execution trace?
I didn't find one, and ended up writing something that's general enough for my needs but not even nearly appropriate for general use. One big problem is that any code can call native code, and most code does that very often, so the tracer only traces a few instructions before encountering a CallInst it cannot handle.
If you're only interested in very short instruction sequences, the functions in Analysis/ConstantFolding.h may be helpful... or may not, it depends on your purpose. If you have to write a tracer yourself, you might want to look around for code that uses InstVisitor, some of that code may be usable, reusable, or a good starting point. Good luck.

How to use comments in LLVM IR in my pass?

Is it possible to use the comments in IR in my pass? Basically I want to use the IR annotated with basic block frequency, which is written in comments, as shown below, and I need the frequency value in my pass. I know this is naive method, but it will suffice.
define internal void #MDFilter() #0 {
entry:
;;; Basic block executed 2 times. <-- I NEED THIS COMMENT AS A STRING IN MY PASS
%mdContext = alloca %struct.MD5_CTX, align 8
%bytes = alloca i32, align 4
%data = alloca [16 x i8], align 16
call void #MD5Init(%struct.MD5_CTX* %mdContext)
br label %while.cond
;;; Out-edge counts: [2.000000e+00 -> while.cond]
Any other method to obtain this info is also welcome.
No, there is no way to use the comments' contents this way, not without significantly changing the IR parser. However, there's no need to re-invent the wheel; there's a mechanism in LLVM which is intended precisely for these sorts of things - transferring information from the front-end into an LLVM pass - and that is metadata.
So whatever or whoever is adding this information to the IR should add it with metadata instead - see these sources for more information on how to do that:
http://llvm.org/docs/LangRef.html#metadata
http://llvm.org/docs/LangRef.html#named-metadata
Adding Metadata to Instructions in LLVM IR
How to attach metadata to LLVM IR using the C++ API?
How to add a Metadata String to an LLVM module with the C++ API?
If you have no control over the generation of data, then you should add some pre-processing step in which you convert the comments to metadata.
In the end the IR should look something like:
define internal void #MDFilter() #0 {
entry:
%mdContext = alloca %struct.MD5_CTX, align 8, !freq !1
%bytes = alloca i32, align 4
%data = alloca [16 x i8], align 16
call void #MD5Init(%struct.MD5_CTX* %mdContext)
br label %while.cond, !outedge !2
...
!1 = metadata !{i32 2}
!2 = metadata !{float 2.0}
And your pass needs to look for these !freq and !outedge nodes.

llvm get global definition line number

I followed the How to get variable definition line number etc. using dbg metadata? in order to get the line number definition for local variables (allocas), which works fine. But I need the same for globals. So I tried to hack the findDbgGlobalDeclare() method from http://llvm.org/docs/doxygen/html/DbgInfoPrinter_8cpp_source.html#l00062 . However, I have no llvm.dbg.gv in my bytecode, so there is no dbg info to extract. I compile my target code using clang++ -O0 -g -emit-llvm Test.cpp -c -o Test.bc . Some samples from my bytecode:
#r = global i32 3, align 4
%4 = load i32* #r, align 4, !dbg !942
...
%a = alloca i32, align 4
%1 = load i32* %a, align 4, !dbg !939
However, I do have:
!924 = metadata !{i32 786484, i32 0, null, metadata !"r", metadata !"r", metadata !"", metadata !841, i32 19, metadata !56, i32 0, i32 1, i32* #r} ; [ DW_TAG_variable ] [r] [line 19] [def]
with on which !0 is indirectly dependent and there is !llvm.dbg.cu = !{!0} .
Thank you !
Yes, !llvm.dbg.cu is the right place now. Quoting from the source-level debugging document:
Compile unit descriptors provide the root context for objects declared
in a specific compilation unit. File descriptors are defined using
this context. These descriptors are collected by a named metadata
!llvm.dbg.cu. They keep track of subprograms, global variables and
type information.
Specifically, see "Global variable descriptors".
The code you found is to support the older metadata nodes which are still generated by dragonegg so the readers support them for backwards compatibility. New LLVM code generates !llvm.dbg.cu.
The steps are as follows:
1. NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.cu");
Then get into the metadata nodes chain till the desired global declaration.
2. DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
3. DIDescriptor DIGG(cast<MDNode>(NMD->getOperand(NMD->getNumOperands()-1)));
4. DIDescriptor DIGF(cast<MDNode>(DIGG->getOperand(0)));
5. Value* VV = cast<Value>(DIGF->getOperand(i));
6. DIDescriptor DIGS(cast<MDNode>(VV));
At this point, do:
7. DIGS->getOperand(j)
and check http://llvm.org/docs/SourceLevelDebugging.html#c-c-front-end-specific-debug-information for all the fields you desire.