Nisal Menuka via llvm-dev
2017-Oct-25 23:21 UTC
[llvm-dev] How vregs are assigned to operands in IR
Hi, I'm trying to understand how virtual regs are assigned to operands in IR instructions. I looked into SelectionDAG but could not figure out where the assignment happens. How and where does this conversion happen? Furthermore, I want to build a map between variable and the virtual register (x corresponds to vreg11 in below code). I've been stuck here for a while. Any help is greatly appreciated. C code int main () { int x, y, z; x = 5; y = 6; z = x + y; printf("integer value %d\n", z); return 0; } Generated IR define i32 @main() #0 { entry: %retval = alloca i32, align 4 %x = alloca i32, align 4 %y = alloca i32, align 4 %z = alloca i32, align 4 store i32 0, i32* %retval, align 4 store i32 5, i32* %x, align 4 store i32 6, i32* %y, align 4 %0 = load i32, i32* %x, align 4 %1 = load i32, i32* %y, align 4 %add = add nsw i32 %0, %1 store i32 %add, i32* %z, align 4 %2 = load i32, i32* %z, align 4 %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i32 0, i32 0), i32 %2) ret i32 0 } Generated machine instructions (initial) BB#0: derived from LLVM BB %entry %vreg11<def> = MOVi32imm 6; GPR32:%vreg11 %vreg12<def> = MOVi32imm 5; GPR32:%vreg12 STRWui %WZR, <fi#0>, 0; mem:ST4[FixedStack0] STRWui %vreg12, <fi#1>, 0; mem:ST4[FixedStack1] GPR32:%vreg12 STRWui %vreg11, <fi#2>, 0; mem:ST4[FixedStack2] GPR32:%vreg11 ................................. Best Nisal
Friedman, Eli via llvm-dev
2017-Oct-25 23:44 UTC
[llvm-dev] How vregs are assigned to operands in IR
On 10/25/2017 4:21 PM, Nisal Menuka via llvm-dev wrote:> Hi, > I'm trying to understand how virtual regs are assigned to operands in > IR instructions. I looked into SelectionDAG but could not figure out > where the assignment happens. How and where does this conversion > happen? > Furthermore, I want to build a map between variable and the virtual > register (x corresponds to vreg11 in below code). > I've been stuck here for a while. Any help is greatly appreciated.InstrEmitter::CreateVirtualRegisters actually creates the registers. See http://llvm.org/docs/CodeGenerator.html#instruction-selection-section for more info on how instruction selection works. "-debug" output might also be helpful to get a brief outline of what's happening. That said, you probably don't want to reinvent debug info. See http://llvm.org/docs/SourceLevelDebugging.html . -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Matthias Braun via llvm-dev
2017-Oct-26 00:29 UTC
[llvm-dev] How vregs are assigned to operands in IR
> On Oct 25, 2017, at 4:21 PM, Nisal Menuka via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi, > I'm trying to understand how virtual regs are assigned to operands in > IR instructions. I looked into SelectionDAG but could not figure out > where the assignment happens. How and where does this conversion > happen? > Furthermore, I want to build a map between variable and the virtual > register (x corresponds to vreg11 in below code).For IR-Values: It is best not to think about something like %x in IR as a variable. They rather are names for a value to help debugging. And when thinking about values you best consider them pointers to a single instruction or to constants. LLVM gives no hard guarantees about those names. They are mainly intended as debugging helpers. There may be cases where they don't clearly correspond to variables in the C program; transformations may invent new names or change existing ones. It will also be equally brittle trying to map vregs to IR values. Among other things legalizations may split a value across multiple vregs, or IR values may be folded as part of a bigger instruction pattern. As Eli mentioned you should rather work with debug information when you want a better mapping of MIR constructs to source code. Even that isn't perfect, but it should be a lot better than any ad-hoc mapping you can come up with. - Matthias> I've been stuck here for a while. Any help is greatly appreciated. > > C code > int main () { > > int x, y, z; > x = 5; > y = 6; > z = x + y; > printf("integer value %d\n", z); > return 0; > } > > Generated IR > > define i32 @main() #0 { > entry: > %retval = alloca i32, align 4 > %x = alloca i32, align 4 > %y = alloca i32, align 4 > %z = alloca i32, align 4 > store i32 0, i32* %retval, align 4 > store i32 5, i32* %x, align 4 > store i32 6, i32* %y, align 4 > %0 = load i32, i32* %x, align 4 > %1 = load i32, i32* %y, align 4 > %add = add nsw i32 %0, %1 > store i32 %add, i32* %z, align 4 > %2 = load i32, i32* %z, align 4 > %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 > x i8], [18 x i8]* @.str, i32 0, i32 0), i32 %2) > ret i32 0 > } > > > Generated machine instructions (initial) > > BB#0: derived from LLVM BB %entry > %vreg11<def> = MOVi32imm 6; GPR32:%vreg11 > %vreg12<def> = MOVi32imm 5; GPR32:%vreg12 > STRWui %WZR, <fi#0>, 0; mem:ST4[FixedStack0] > STRWui %vreg12, <fi#1>, 0; mem:ST4[FixedStack1] GPR32:%vreg12 > STRWui %vreg11, <fi#2>, 0; mem:ST4[FixedStack2] GPR32:%vreg11 > ................................. > > Best > Nisal > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Nisal Menuka via llvm-dev
2017-Oct-26 05:05 UTC
[llvm-dev] How vregs are assigned to operands in IR
Hi, Thanks, I will try to see if I can get anything from InstrEmitter::CreateVirtualRegisters, otherwise will try to look in to debug info. I was trying to map Value object for x (from I->getOperand()), I noticed that it remains the same through all the instructions that are used in IR. I assume x is not assigned again in my program, so I believe x should correspond to only a single vreg. Is this correct? Best Nisal On Wed, Oct 25, 2017 at 7:29 PM, Matthias Braun <mbraun at apple.com> wrote:> >> On Oct 25, 2017, at 4:21 PM, Nisal Menuka via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> >> Hi, >> I'm trying to understand how virtual regs are assigned to operands in >> IR instructions. I looked into SelectionDAG but could not figure out >> where the assignment happens. How and where does this conversion >> happen? >> Furthermore, I want to build a map between variable and the virtual >> register (x corresponds to vreg11 in below code). > For IR-Values: It is best not to think about something like %x in IR as a variable. > They rather are names for a value to help debugging. And when thinking about values you best consider them pointers to a single instruction or to constants. > > LLVM gives no hard guarantees about those names. > They are mainly intended as debugging helpers. > There may be cases where they don't clearly correspond to variables in the C program; transformations may invent new names or change existing ones. > > It will also be equally brittle trying to map vregs to IR values. Among other things legalizations may split a value across multiple vregs, or IR values may be folded as part of a bigger instruction pattern. > > As Eli mentioned you should rather work with debug information when you want a better mapping of MIR constructs to source code. Even that isn't perfect, but it should be a lot better than any ad-hoc mapping you can come up with. > > - Matthias > >> I've been stuck here for a while. Any help is greatly appreciated. >> >> C code >> int main () { >> >> int x, y, z; >> x = 5; >> y = 6; >> z = x + y; >> printf("integer value %d\n", z); >> return 0; >> } >> >> Generated IR >> >> define i32 @main() #0 { >> entry: >> %retval = alloca i32, align 4 >> %x = alloca i32, align 4 >> %y = alloca i32, align 4 >> %z = alloca i32, align 4 >> store i32 0, i32* %retval, align 4 >> store i32 5, i32* %x, align 4 >> store i32 6, i32* %y, align 4 >> %0 = load i32, i32* %x, align 4 >> %1 = load i32, i32* %y, align 4 >> %add = add nsw i32 %0, %1 >> store i32 %add, i32* %z, align 4 >> %2 = load i32, i32* %z, align 4 >> %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 >> x i8], [18 x i8]* @.str, i32 0, i32 0), i32 %2) >> ret i32 0 >> } >> >> >> Generated machine instructions (initial) >> >> BB#0: derived from LLVM BB %entry >> %vreg11<def> = MOVi32imm 6; GPR32:%vreg11 >> %vreg12<def> = MOVi32imm 5; GPR32:%vreg12 >> STRWui %WZR, <fi#0>, 0; mem:ST4[FixedStack0] >> STRWui %vreg12, <fi#1>, 0; mem:ST4[FixedStack1] GPR32:%vreg12 >> STRWui %vreg11, <fi#2>, 0; mem:ST4[FixedStack2] GPR32:%vreg11 >> ................................. >> >> Best >> Nisal >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >
Maybe Matching Threads
- [LLVMdev] Strong vs. default phi elimination and single-reg classes
- [LLVMdev] Strong vs. default phi elimination and single-reg classes
- [LLVMdev] register allocation problems in trunk with IMPLICIT_DEF
- [LLVMdev] register allocation problems in trunk with IMPLICIT_DEF
- [LLVMdev] register allocation problems in trunk with IMPLICIT_DEF