I was handed a makefile which is used to compile a library and was told to figure out why the compilation is failing.
There is a lot of output and at this point I’m not sure what is important and what is not. I’m trying to solve this problem in small steps, so if asked I can certainly provide more information.
The first error that I see during compilation is
lib/CodeGen/MachineScheduler.cpp:1165: void llvm::ScheduleDAGMILive::scheduleMI(llvm::SUnit*, bool): Assertion `TopRPTracker.getPos() == CurrentTop && “out of sync”’ failed.
Another important detail is that we are running clang-3.5. I know it is old, but for now we are not allowed to switch to a newer version.
I would greatly appreciate any help on this. What is causing this assertion? Is there a way to fix it? Could there something be wrong with the input file? I do have access to the llvm code and have the freedom to change it.
Any advice or help is appreciated.
This happens on Hexagon too. I have a patch for review:
http://reviews.llvm.org/D19438
-Krzysztof
Thanks for the suggestion.
I tried your fix. It worked for my particular case, but then I got a following error:
clang-3.5: /home/rail/projects/escala_llvm/trunk/llvm-or1k/lib/CodeGen/RegisterPressure.cpp:39: void decreaseSetPressure(std::vector&, llvm::PSetIterator): Assertion `CurrSetPressure[*PSetI] >= Weight && “register pressure underflow”’ failed.
Do you mind helping me out? A stack dump is provided below:
clang-3.5: /home/rail/projects/escala_llvm/trunk/llvm-or1k/lib/CodeGen/RegisterPressure.cpp:39: void decreaseSetPressure(std::vector&, llvm::PSetIterator): Assertion `CurrSetPressure[PSetI] >= Weight && “register pressure underflow”’ failed.
0 clang-3.5 0x00000000017dfae4 llvm::sys::PrintStackTrace(_IO_FILE) + 38
1 clang-3.5 0x00000000017dfd61
2 clang-3.5 0x00000000017df715
3 libpthread.so.0 0x00002ad3b4a17340
4 libc.so.6 0x00002ad3b547bcc9 gsignal + 57
5 libc.so.6 0x00002ad3b547f0d8 abort + 328
6 libc.so.6 0x00002ad3b5474b86
7 libc.so.6 0x00002ad3b5474c32
8 clang-3.5 0x0000000001de82a3
9 clang-3.5 0x0000000001de880c llvm::RegPressureTracker::decreaseRegPressure(llvm::ArrayRef) + 120
10 clang-3.5 0x0000000001dec305 llvm::RegPressureTracker::bumpDownwardPressure(llvm::MachineInstr const*) + 593
11 clang-3.5 0x0000000001dec4da llvm::RegPressureTracker::getMaxDownwardPressureDelta(llvm::MachineInstr const*, llvm::RegPressureDelta&, llvm::ArrayRefllvm::PressureChange, llvm::ArrayRef) + 138
12 clang-3.5 0x0000000000e4c60f
13 clang-3.5 0x0000000000e4f066 llvm::ConvergingVLIWScheduler::pickNodeFromQueue(llvm::ReadyQueue&, llvm::RegPressureTracker const&, llvm::ConvergingVLIWScheduler::SchedCandidate&) + 284
14 clang-3.5 0x0000000000e4f2e5 llvm::ConvergingVLIWScheduler::pickNodeBidrectional(bool&) + 285
15 clang-3.5 0x0000000000e4f5b0 llvm::ConvergingVLIWScheduler::pickNode(bool&) + 576
16 clang-3.5 0x0000000000e4db8e llvm::VLIWMachineScheduler::schedule() + 1366
17 clang-3.5 0x0000000001d7830f
18 clang-3.5 0x0000000001d77988
19 clang-3.5 0x0000000001d4f9c7 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 95
20 clang-3.5 0x00000000014dacee llvm::FPPassManager::runOnFunction(llvm::Function&) + 290
21 clang-3.5 0x00000000014dae5e llvm::FPPassManager::runOnModule(llvm::Module&) + 84
22 clang-3.5 0x00000000014db17c
23 clang-3.5 0x00000000014db766 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 244
24 clang-3.5 0x00000000014db971 llvm::legacy::PassManager::run(llvm::Module&) + 39
25 clang-3.5 0x0000000001ef9c4b
26 clang-3.5 0x0000000001ef9d1a clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 127
27 clang-3.5 0x0000000001ef3637
28 clang-3.5 0x000000000276b1ea clang::ParseAST(clang::Sema&, bool, bool) + 780
29 clang-3.5 0x00000000019992b0 clang::ASTFrontendAction::ExecuteAction() + 322
30 clang-3.5 0x0000000001ef4fb8 clang::CodeGenAction::ExecuteAction() + 1362
31 clang-3.5 0x0000000001998de3 clang::FrontendAction::Execute() + 205
32 clang-3.5 0x000000000196c770 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 720
33 clang-3.5 0x0000000001a8b277 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1029
34 clang-3.5 0x0000000000e36a09 cc1_main(char const**, char const**, char const*, void*) + 717
35 clang-3.5 0x0000000000e312f4 main + 785
36 libc.so.6 0x00002ad3b5466ec5 __libc_start_main + 245
37 clang-3.5 0x0000000000e2e959
Are there any instructions (other than COPY) that use hardware (allocatable) registers?
Could you show the instructions in the scheduling range?
-Krzysztof
Apologies if my questions sound dumb. They are provided below.
Are there any instructions (other than COPY) that use hardware
(allocatable) registers?
How do I find that out?
Could you show the instructions in the scheduling range?
How can I see instructions in the current scheduling range?
I’m attaching an output of -mllvm -debug command. The output is large but i’m hoping it contains everything that is needed. If anyone needs more, just ask.
Any help in resolving the issue is appreciated.
debug.log (3.59 MB)
There are uses of R0 all over the place, even though R0 is not marked as live-in to any of the blocks that use it. For example:
BB#45: derived from LLVM BB %sw.bb54
Predecessors according to CFG: BB#43 BB#44
DBG_VALUE %vreg287, %noreg, !"base"
%vreg203<def> = LWZ <fi#5>, 0; mem:LD4[%args] GPR:%vreg203
%vreg204<def> = ADDI %vreg203, 3; GPR:%vreg204,%vreg203
--> %vreg205<def> = ADDI %R0, -4; GPR:%vreg205
%vreg206<def> = AND %vreg204, %vreg205; GPR:%vreg206,%vreg204,%vreg205
%vreg207<def> = ADDI %vreg206, 4; GPR:%vreg207,%vreg206
%vreg290<def> = LWZ %vreg206, 0; mem:LD4[<unknown>] GPR:%vreg290,%vreg206
SFGTS_ri %vreg290, -1, %SR<imp-def>; GPR:%vreg290
BF <BB#48>, %SR<imp-use,kill>
J <BB#46>
Successors according to CFG: BB#46(186) BB#48(62)
IIRC, at some point the register pressure tracker assumed that a use of a physical register is always a kill, thus it would always decrease register pressure on the class that the register belonged to. If that assumption is false, the decrease would be incorrect and could lead to an underflow.
The "proper" usage of a physical register would be to mark it as a live-in to the block, and then have a COPY instruction that would transfer it into a virtual register, which would then be used in the ADDI.
Since you are using llvm 3.5, that may still be the case for you. I'm not sure whether this is still necessary in ToT.
-Krzysztof
There are uses of R0 all over the place, even though R0 is not marked as
live-in to any of the blocks that use it. For example:
For my architecture R0 is a physical register. It always has a value of 0.
BB#45: derived from LLVM BB %sw.bb54
Predecessors according to CFG: BB#43 BB#44
DBG_VALUE %vreg287, %noreg, !"base"
%vreg203<def> = LWZ <fi#5>, 0; mem:LD4[%args] GPR:%vreg203
%vreg204<def> = ADDI %vreg203, 3; GPR:%vreg204,%vreg203
--> %vreg205<def> = ADDI %R0, -4; GPR:%vreg205
%vreg206<def> = AND %vreg204, %vreg205;
GPR:%vreg206,%vreg204,%vreg205
%vreg207<def> = ADDI %vreg206, 4; GPR:%vreg207,%vreg206
%vreg290<def> = LWZ %vreg206, 0; mem:LD4[<unknown>]
GPR:%vreg290,%vreg206
SFGTS_ri %vreg290, -1, %SR<imp-def>; GPR:%vreg290
BF <BB#48>, %SR<imp-use,kill>
J <BB#46>
Successors according to CFG: BB#46(186) BB#48(62)
IIRC, at some point the register pressure tracker assumed that a use of a
physical register is always a kill, thus it would always decrease register
pressure on the class that the register belonged to.
Am I correct assuming that kill means get rid of the register?
If that assumption is false, the decrease would be incorrect and could
lead to an underflow.
The "proper" usage of a physical register would be to mark it as a live-in
to the block, and then have a COPY instruction that would transfer it into
a virtual register, which would then be used in the ADDI.
Does it mean that I have to make changes to the core code (register
pressure tracker) or I can get away with changes to my target? Obviously
the latter is preferred.
Since you are using llvm 3.5, that may still be the case for you. I'm not
sure whether this is still necessary in ToT.
Am I correct assuming that by the "case" you mean kill of the physical
register? I'm not familiar with ToT abbreviation? What does it mean?
There are uses of R0 all over the place, even though R0 is not
marked as live-in to any of the blocks that use it. For example:
For my architecture R0 is a physical register. It always has a value of 0.
Ah, ok. I'm guessing it's already marked as "reserved", right?
IIRC, at some point the register pressure tracker assumed that a use
of a physical register is always a kill, thus it would always
decrease register pressure on the class that the register belonged to.
Am I correct assuming that kill means get rid of the register?
Kill is the last use of the register after its most recent definition. After this point the register is "dead", i.e. no longer used.
Does it mean that I have to make changes to the core code (register
pressure tracker) or I can get away with changes to my target? Obviously
the latter is preferred.
If R0 is reserved, you should be fine without any changes. In such case, I don't really know what the problem is. I still suspect that the R0 is not handled right somewhere, but I have no idea where exactly.
Since you are using llvm 3.5, that may still be the case for you.
I'm not sure whether this is still necessary in ToT.
Am I correct assuming that by the "case" you mean kill of the physical
register? I'm not familiar with ToT abbreviation? What does it mean?
ToT = tip of the tree, the latest source tree of LLVM/clang.
-Krzysztof
There are uses of R0 all over the place, even though R0 is not
marked as live-in to any of the blocks that use it. For example:
For my architecture R0 is a physical register. It always has a value of 0.
Ah, ok. I'm guessing it's already marked as "reserved", right?
IIRC, at some point the register pressure tracker assumed that a use
of a physical register is always a kill, thus it would always
decrease register pressure on the class that the register belonged to.
Am I correct assuming that kill means get rid of the register?
Kill is the last use of the register after its most recent definition.
After this point the register is "dead", i.e. no longer used.
Does it mean that I have to make changes to the core code (register
pressure tracker) or I can get away with changes to my target? Obviously
the latter is preferred.
If R0 is reserved, you should be fine without any changes. In such case,
I don't really know what the problem is. I still suspect that the R0 is
not handled right somewhere, but I have no idea where exactly.
Register R0 is indeed reserved. Would you have any suggestions on where to
look for the problem? I'd appreciate any input on this.
If I remember correctly...
-Krzysztof
IIRC,
What is IIRC?
If I remember correctly...
LOL !!! I thought it was some sort of LLVM abbreviation.
Krzysztof,
If you are curious I managed to fix an issue. It is a little embarrassing to admit but the fix you suggested worked. I think I was just too tired when I put in my code. It turns out that I made a few mistakes while implementing your solution.
I really appreciate your help.
No worries, we've all been there. I'm glad I could help. 
-Krzysztof