t-crest / patmos-llvm Goto Github PK
View Code? Open in Web Editor NEWPort of the LLVM compiler infrastructure to the time-predictable processor Patmos
License: Other
Port of the LLVM compiler infrastructure to the time-predictable processor Patmos
License: Other
When I compile a program that includes a divide operation to bitcode (using patmos-clang -S
) and then try to further compile it to assembly with patmos-llc
, using the singlepath flag, it crashes.
Take this minimal code (we will refer to this as main.c
):
volatile int _1 = 1;
volatile int _2 = 2;
int main(){
return _2 / _1;
}
We compile it to LLVM bitcode using the command patmos-clang -S main.c -O2
without issue.
We then try to compile it to assembly using the command patmos-llc main.s -mpatmos-singlepath=main -O2
. This fails with the following error:
[Single-path] Cannot rewrite call in main (indirect call?)
0 libLLVMSupport.so 0x00007f2c15841762 llvm::sys::PrintStackTrace(_IO_FILE*) + 50
1 libLLVMSupport.so 0x00007f2c15840f4c
2 libc.so.6 0x00007f2c1503ef20
3 libc.so.6 0x00007f2c1503ee97 gsignal + 199
4 libc.so.6 0x00007f2c15040801 abort + 321
5 libLLVMPatmosCodeGen.so 0x00007f2c175a5875
6 libLLVMCore.so 0x00007f2c15e50d09 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 761
7 patmos-llc 0x00007f2c18008294
8 patmos-llc 0x00007f2c18006ec0
9 libc.so.6 0x00007f2c15021b97 __libc_start_main + 231
10 patmos-llc 0x00007f2c18006f3a
Stack dump:
0. Program arguments: patmos-llc main.s -mpatmos-singlepath=main -O2
1. Running pass 'Patmos Single-Path Mark (machine code)' on module 'main.s'.
Note that we are using -O2
, but all other optimization levels result in the same issue. The issue is only present with the divide operator, changing it to a multiply makes the code compile successfully.
Additionally, the issue is only present when first compiling to bitcode and then using patmos-llc
on it. If we instead use the command patmos-clang main.c
the code compiles successfully. So the issue is caused by patmos-llc
having to read bitcode.
When i try to compile patmos-clang for ARM i am getting no available target error...
~/t-crest$ patmos-clang -target arm-linux-gnueabi -marm -mserialize=/home/soma/if-testpat34.pml /home/soma/if-test34.c
patmos-clang-3.4: warning: argument unused during compilation: '-mserialize=/home/soma/if-testpat34.pml'
error: unable to create target: 'No available targets are compatible with this
triple, see -version for the available targets.'
1 error generated.
Hi
I am writing a message passing interface, for patmos.
When trying to compile the code I get the following output:
helena:~/t-crest/patmos/c $ make libmp
mkdir -p ../tmp/libmp/
patmos-clang -target patmos-unknown-unknown-elf -O2 -I/home/rboso/t- crest/patmos/c -mpatmos-disable-vliw -c -o ../tmp/libmp/mp.o libmp/mp.c
patmos-clang-3.4: warning: argument unused during compilation: '-mpatmos-disable-vliw'
patmos-clang-3.4: /home/rboso/t-crest/llvm/lib/IR/Instructions.cpp:2352: static llvm::CastInst* llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, const llvm::Twine&, llvm::Instruction*): Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' failed.
0 libLLVMSupport.so 0x00002b7bcc17af5f llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1 libLLVMSupport.so 0x00002b7bcc17b1dc
2 libLLVMSupport.so 0x00002b7bcc17ac32
3 libc.so.6 0x00002b7bcd6d7ff0
4 libc.so.6 0x00002b7bcd6d7f77 gsignal + 55
5 libc.so.6 0x00002b7bcd6db5e8 abort + 328
6 libc.so.6 0x00002b7bcd6d0d43
7 libc.so.6 0x00002b7bcd6d0df2
8 libLLVMCore.so 0x00002b7bcb8fd17b llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*) + 87
9 libclangCodeGen.so 0x00002b7bd019f09b
10 libclangCodeGen.so 0x00002b7bd019ddf2
11 libclangCodeGen.so 0x00002b7bd02a4c00
12 libclangCodeGen.so 0x00002b7bd02a50e8
13 libclangCodeGen.so 0x00002b7bd029b04a
14 libclangCodeGen.so 0x00002b7bd02a9946
15 libclangCodeGen.so 0x00002b7bd0299a7d
16 libclangCodeGen.so 0x00002b7bd029f3a0
17 libclangCodeGen.so 0x00002b7bd02aaf77
18 libclangCodeGen.so 0x00002b7bd02aa2c9
19 libclangCodeGen.so 0x00002b7bd0299a7d
20 libclangCodeGen.so 0x00002b7bd02a8f67 clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) + 159
21 libclangCodeGen.so 0x00002b7bd023c8c3 clang::CodeGen::CodeGenFunction::EmitScalarInit(clang::Expr const*, clang::ValueDecl const*, clang::CodeGen::LValue, bool) + 99
22 libclangCodeGen.so 0x00002b7bd023eff1 clang::CodeGen::CodeGenFunction::EmitExprAsInit(clang::Expr const*, clang::ValueDecl const*, clang::CodeGen::LValue, bool) + 425
23 libclangCodeGen.so 0x00002b7bd023e932 clang::CodeGen::CodeGenFunction::EmitAutoVarInit(clang::CodeGen::CodeGenFunction::AutoVarEmission const&) + 810
24 libclangCodeGen.so 0x00002b7bd023d7a8 clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(clang::VarDecl const&) + 58
25 libclangCodeGen.so 0x00002b7bd023aec5 clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) + 239
26 libclangCodeGen.so 0x00002b7bd023ad83 clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl const&) + 355
27 libclangCodeGen.so 0x00002b7bd0310aab clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) + 107
28 libclangCodeGen.so 0x00002b7bd030e01b clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*) + 247
29 libclangCodeGen.so 0x00002b7bd030dacd clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*) + 73
30 libclangCodeGen.so 0x00002b7bd030e2a9 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) + 109
31 libclangCodeGen.so 0x00002b7bd032e9dd clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::CodeGen::FunctionArgList&, clang::Stmt const*) + 79
32 libclangCodeGen.so 0x00002b7bd032f10a clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) + 1338
33 libclangCodeGen.so 0x00002b7bd033ea01 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl) + 1051
34 libclangCodeGen.so 0x00002b7bd033beb2 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl) + 396
35 libclangCodeGen.so 0x00002b7bd033b7dd clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) + 673
36 libclangCodeGen.so 0x00002b7bd034205f clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) + 307
37 libclangCodeGen.so 0x00002b7bd03b232a
38 libclangCodeGen.so 0x00002b7bd032a6a4
39 libclangParse.so 0x00002b7bd211173e clang::ParseAST(clang::Sema&, bool, bool) + 554
40 libclangFrontend.so 0x00002b7bcce816e6 clang::ASTFrontendAction::ExecuteAction() + 322
41 libclangCodeGen.so 0x00002b7bd0329555 clang::CodeGenAction::ExecuteAction() + 1145
42 libclangFrontend.so 0x00002b7bcce81229 clang::FrontendAction::Execute() + 205
43 libclangFrontend.so 0x00002b7bcce4ee32 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 720
44 libclangFrontendTool.so 0x00002b7bcc3ebcbf clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1026
45 patmos-clang-3.4 0x0000000000416ad7 cc1_main(char const**, char const**, char const*, void*) + 717
46 patmos-clang-3.4 0x000000000041126b main + 785
47 libc.so.6 0x00002b7bcd6c2de5 __libc_start_main + 245
48 patmos-clang-3.4 0x000000000040fd69
Stack dump:
0. Program arguments: /home/rboso/t-crest/local/bin/patmos-clang-3.4 -cc1 -triple patmos-unknown-unknown-elf -emit-llvm-bc -disable-free -main-file-name mp.c -mrelocation-model static -fmath-errno -masm-verbose -mconstructor-aliases -nostdsysteminc -msoft-float -mfloat-abi soft -momit-leaf-frame-pointer -coverage-file /home/rboso/t-crest/patmos/c/../tmp/libmp/mp.o -resource-dir /home/rboso/t-crest/local/bin/../lib/clang/3.4 -I /home/rboso/t-crest/patmos/c -isystem /home/rboso/t-crest/local/bin/../patmos-unknown-unknown-elf/include/ -O2 -fdebug-compilation-dir /home/rboso/t-crest/patmos/c -ferror-limit 19 -fmessage-length 162 -mstackrealign -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o ../tmp/libmp/mp.o -x c libmp/mp.c
1. libmp/mp.c:81:1: current parser token 'void'
2. libmp/mp.c:67:6: LLVM IR generation of declaration 'mp_send'
3. libmp/mp.c:67:6: Generating code for declaration 'mp_send'
patmos-clang-3.4: error: unable to execute command: Aborted (core dumped)
patmos-clang-3.4: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 3.4
Target: patmos-unknown-unknown-elf
Thread model: posix
patmos-clang-3.4: note: diagnostic msg: PLEASE submit a bug report to https://github.com/t-crest/patmos-llvm/issues and include the crash backtrace, preprocessed source, and associated run script.
patmos-clang-3.4: note: diagnostic msg:
*******************
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
patmos-clang-3.4: note: diagnostic msg: /tmp/mp-bb2927.c
patmos-clang-3.4: note: diagnostic msg: /tmp/mp-bb2927.sh
patmos-clang-3.4: note: diagnostic msg:
********************
I have the diagnostic messages and the files I am trying to compile, who should I send it to? I can only attach images to this issue
/Rasmus
Compilation fails on MacOs. When I run it, I get an error about various labels being undefined for x86_64:
Undefined symbols for architecture x86_64:
"llvm::MachineInstr::addOperand(llvm::MachineFunction&, llvm::MachineOperand const&)", referenced from:
(anonymous namespace)::PatmosSPMark::runOnMachineModule(llvm::Module const&) in PatmosSPMark.cpp.o
llvm::PatmosSPReduce::applyPredicates(llvm::SPScope*, llvm::MachineFunction&) in PatmosSPReduce.cpp.o
llvm::PatmosSPReduce::insertStackLocInitializations(llvm::SPScope*) in PatmosSPReduce.cpp.o
llvm::PatmosSPReduce::insertDefToRegLoc(llvm::MachineBasicBlock&, unsigned int, unsigned int, llvm::SmallVectorImpl<llvm::MachineOperand> const&, bool, bool, bool) in PatmosSPReduce.cpp.o
llvm::PatmosSPReduce::insertDefToS0SpillSlot(llvm::MachineBasicBlock&, unsigned int, unsigned int, unsigned int, llvm::SmallVectorImpl<llvm::MachineOperand> const&) in PatmosSPReduce.cpp.o
llvm::PatmosSPReduce::insertDefToStackLoc(llvm::MachineBasicBlock&, unsigned int, unsigned int, llvm::SmallVectorImpl<llvm::MachineOperand> const&) in PatmosSPReduce.cpp.o
llvm::PatmosSPReduce::insertUseSpillLoad(llvm::RAInfo const&, llvm::_PredicatedBlock<llvm::MachineBasicBlock, llvm::MachineInstr, llvm::MachineOperand>*) in PatmosSPReduce.cpp.o
...
This is not necessarily an issue with the code, as it also doesn't compile on bc4cc75.
Even going back to before I began committing, and patching it like bc4cc75, it still doesn't compile.
Therefore, this might have something to do with the age of the project, and could be solved by updating to a newer version of LLVM.
While looking at which instruction selection optimizations we do, I fell on the following sentence:
// following mul by constant patterns only pay off if mul takes > 2 cycles
// and offers no immediate variant
This implies that the mul
instruction requires a different number of cycles depending on the input.
Therefore, I have the following questions:
mul
actually take a different number of cycles based on input?mul
will take depending on input?Is there something related to x86 hardcoded?
llvm::SPScope::SPScope(llvm::SPScope*, llvm::MachineLoop&, llvm::MachineFunction&, llvm::MachineLoopInfo&) in SPScope.cpp.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [lib/libLLVMPatmosSinglePath.dylib] Error 1
make[1]: *** [lib/Target/Patmos/SinglePath/CMakeFiles/LLVMPatmosSinglePath.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[ 45%] Built target LLVMPatmosDesc
make: *** [all] Error 2
llc
crashes on an assertion error when trying to compile a program, using singlepath, where an inner loop breaks out of an outer loop:
#include <stdio.h>
volatile int _1 = 1;
int init_func(int outer, int inner){
int x = 0;
#pragma loopbound min 0 max 10
for(int i = 0; i < outer; i++){
#pragma loopbound min 0 max 4
for(int k = 0; k < 5; k++){
if( (x%100) == inner){
goto breakLoops; // break out of both loops
}
x += _1;
}
x += 100;
}
breakLoops:
return x;
}
int main(){
int outer, inner;
scanf("%d %d", &outer, &inner);
printf("%d\n", init_func(outer, inner));
}
Compiling using the command patmos-clang main.c -mpatmos-singlepath=init_func
results in the following error:
patmos-llc: /home/s123791/emoun/llvm/lib/Target/Patmos/PatmosSPReduce.cpp:1225: void {anonymous}::PatmosSPReduce::insertDefEdge(llvm::SPScope*, llvm::MachineBasicBlock&, unsigned int, llvm::SPScope::Edge): Assertion `!S->isSubHeader(&Node) || (RI.Scope->getParent() == S)' failed.
0 libLLVMSupport.so 0x00007fb9fe9ec39c llvm::sys::PrintStackTrace(_IO_FILE*) + 53
1 libLLVMSupport.so 0x00007fb9fe9ec62c
2 libLLVMSupport.so 0x00007fb9fe9ebfda
3 libc.so.6 0x00007fb9fe18a4b0
4 libc.so.6 0x00007fb9fe18a428 gsignal + 56
5 libc.so.6 0x00007fb9fe18c02a abort + 362
6 libc.so.6 0x00007fb9fe182bd7
7 libc.so.6 0x00007fb9fe182c82
8 libLLVMPatmosCodeGen.so 0x00007fba016669e7
9 libLLVMPatmosCodeGen.so 0x00007fba01666710
10 libLLVMPatmosCodeGen.so 0x00007fba016651fb
11 libLLVMPatmosCodeGen.so 0x00007fba01663362
12 libLLVMCodeGen.so 0x00007fba000cfd07 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 95
13 libLLVMCore.so 0x00007fb9ff258946 llvm::FPPassManager::runOnFunction(llvm::Function&) + 330
14 libLLVMCore.so 0x00007fb9ff258abc llvm::FPPassManager::runOnModule(llvm::Module&) + 120
15 libLLVMCore.so 0x00007fb9ff258dbc
16 libLLVMCore.so 0x00007fb9ff25938f llvm::legacy::PassManagerImpl::run(llvm::Module&) + 267
17 libLLVMCore.so 0x00007fb9ff259569 llvm::legacy::PassManager::run(llvm::Module&) + 39
18 patmos-llc 0x000000000040ce99
19 patmos-llc 0x000000000040beac
20 libc.so.6 0x00007fb9fe175830 __libc_start_main + 240
21 patmos-llc 0x000000000040b779
Stack dump:
0. Program arguments: /home/s123791/emoun/local/bin/patmos-llc -O0 -mforce-block-labels -disable-separate-nested-loops -mpatmos-singlepath=init_func -filetype=obj -o /tmp/a-104e35.bc.o /tmp/a-8e960e.bc
1. Running pass 'Function Pass Manager' on module '/tmp/a-8e960e.bc'.
2. Running pass 'Patmos Single-Path Reducer' on function '@init_func'
patmos-clang-3.4: error: unable to execute command: Aborted (core dumped)
patmos-clang-3.4: error: link via llvm-link, opt and llc command failed due to signal (use -v to see invocation)
Take this program:
define i32 @main() {
entry:
; We make a block of 64 bytes, which can in no way fit in a 32 byte subfunction
%0 = call i32 asm "
li $0 = 4096 # Long arithmetic, 8 bytes each
li $0 = 4096
li $0 = 4096
li $0 = 4096
li $0 = 4096
li $0 = 4096
li $0 = 4096
li $0 = 4096
", "=r"
()
ret i32 %0
}
If we try to compile it with a 32 bytes method cache (llc main.ll -mpatmos-max-subfunction-size=32
), it should fail, as we should not split inside an inline assembly block, and the block is twice the allowed size.
However, this compiles successfully, without splitting the inline assembly block:
.file "<stdin>"
.text
.globl main
.align 16
.type main,@function
.fstart main, .Ltmp0-main, 16
main: # @main
# BB#0:
brcfnd .LBB0_1
.Ltmp0:
.align 16
.type .LBB0_1,@code
.size .LBB0_1, .Ltmp1-.LBB0_1
.fstart .LBB0_1, .Ltmp1-.LBB0_1, 16
.LBB0_1:
#APP
li $r1 = 4096 # Long arithmetic, 8 bytes each
li $r1 = 4096
li $r1 = 4096
li $r1 = 4096
li $r1 = 4096
li $r1 = 4096
li $r1 = 4096
li $r1 = 4096
#NO_APP
brcfnd .LBB0_2
.Ltmp1:
.align 16
.type .LBB0_2,@code
.size .LBB0_2, .Ltmp2-.LBB0_2
.fstart .LBB0_2, .Ltmp2-.LBB0_2, 16
.LBB0_2:
retnd
.LBB0_3: # %entry
nop
.Ltmp2:
.Ltmp3:
.size main, .Ltmp3-main
This should be fixed, so that a compile error is thrown in such situations.
If we compile a program using single-path, and that program includes a conditional return inside a loop, the resulting executable will produce the wrong result.
Take this program (main.c
):
#include <stdio.h>
volatile int _7 = 7;
int init_func(int x){
#pragma loopbound min 0 max 5
while(x > 0){
if(x == _7){
return x;
}
x--;
}
x += 10;
return x;
}
int main(){
int x;
scanf("%d", &x);
printf("%d\n", init_func(x));
}
The program should print 10
if given an input integer below 7
and 7
otherwise. (the highest input integer allowed is 13
). But, if compiled with the command patmos-clang main.c -mpatmos-singlepath
and run on pasim
with the command echo 6 | pasim a.out
, the result is 0
(should be 10
).
For all other inputs the result is correct. For some reason, when x
starts out at 6
, the x += 10;
is skipped.
This error is similar to #19, so they might be caused by the same bug.
We might also note, that if the above program did not have the loop bound pragma, it would compile and execute correctly. However, this is because, without a loop bound, the loop is not generated as single-path code.
patmos-clang always includes whole libraries given on the command line, even if no function from that library is used. For example, when compiling the program "int main() { return 0; }" with "patmos-clang test.c -o test.elf -lm", the resulting file test.elf includes the whole libm, even though there is obviously no reason to pull in the library code.
GCC and LLVM provide the __BYTE_ORDER
to determine what endianess the host system.
The patmos-llvm compiler sets that property incorrectly.
endian.c
int main()
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
printf("Little Endian\n");
#elif __BYTE_ORDER == __BIG_ENDIAN
printf("Big Endian\n");
#else
#error Macro __BYTE_ORDER is neither __LITTLE_ENDIAN nor __BIG_ENDIAN
#endif
}
Expected Behaviour:
Big Endian
Actual Behaviour
Little Endian
Different parts of platin currently fail to process functions with unresolved calls (e.g. flowfact transformation, visualization). @dlp proposed trace analysis to identify some call targets, but this cannot handle calls in parts of the program not executed during the trace. (Platin testcase created here: https://github.com/t-crest/patmos-benchmarks/blob/master/tests/platin/22-call-any.c)
To manually resolve the calls (or ignore them), we could ultimately use
Both should update a programs PML file in some way. 5a6cc5e adds an experimental platin tool to modify program information in a PML file. Program elements are selected by matching an XPath-inspired PMLPath. The only modification action supported right now is --clear-callees (clears the callee list in selected instructions), removing or replacing modifications could be added as well.
The first segment of the path selects the set of bitcode bc
or machine code mc
functions; the following segments represent function, basic block, instruction, respectively. Matching predicates are of the form [@property=name]
, all elements are selected using *
.
The bitcode and the machine code function 'main':
/*/[@label=main]
All blocks in bitcode function 'main':
/bc/[@label=main]/*
All instructions in bitcode function 'main' that call function 'foo':
/bc/[@label=main]/*/[@callees=foo]
Much like with the patmos simulator, I would like to split of the platin
tool into its own repository under t-crest.
platin
doesn't depend on LLVM in any way (it's even written in ruby and not c++) and neither does LLVM directly depend of platin
. Extracting it into its own repository will give us more flexibility and enable us to independently work on it without having to worry about LLVM. It will also allow for a proper CI setup for it.
When compiling from assembly, the bcopy
instruction either cannot be parsed or is parsed incorrectly.
Scenario 1:
If the instruction is written correctly, e.g. bcopy $26 = $25, 0, $p1
, then compilation using patmos-clang
throws the error:
error: too few operands for instruction
bcopy $r26 = $r25, 0, $p1
Scenario 2:
If we add a comma to the end of the operand list, e.g. bcopy $26 = $25, 0, $p1,
then compilation won't fail, but the instruction is not output to the final object file. I.e. its is just ignored.
Both scenarios also manifest in inline assembly, e.g:
int main(){
asm(
"bcopy $r26 = $r25, 0, $p1"
);
}
A customization to LLVM that we have is llvm/CodeGen/MachineModulePass
. The LLVM project has moved in a different direction, so we should get ready to do so too.
Back when we implemented MachineModulePass
there was no way in LLVM to do so. Therefore, we added it to LLVM with the hope that some day LLVM would also provide it.
After looking into the history of this feature, I have concluded that the LLVM project decided on a different API for doing "machine module passes".
From what I can tell, they edited the codegen step of the backend to allow ModulePass
to be used in it. This means MachineModulePasses
can simply extend ModulePass
.
As a result, I propose to move MachineModulePass
into the Patmos folder for now. Then, as we port to LLVM 11, we switch to using the LLVM machine module pass infrastructure.
Note: I made a gist summarizing my finding with sources for anyone interested: here.
When a function is split into subfunctions, the symbol for each subfunction (but not the main function) is given the @code
ELF symbol type.
The type value is 13, which the first available in the processor specific symbol types ELF has free (STT_LOPROC->STT_HIPROC) and as such is valid.
LLVM does not have native support for using processor specific symbol types, and as such the existing implementation edits various LLVM files to add the capability to the patmos backend.
This issue proposes dropping the use of this symbol type to avoid this processor specific code.
As far as I can tell, the symbol type is not used by other tools and the nightly test works fine if the code that emits this symbol type is removed.
If anyone has knowledge of this symbol type being used somewhere in this project please let me know.
Take the following LLVM program (main.s
):
@_7 = global i32 7
define i32 @main() {
entry:
%0 = load volatile i32* @_7
%tobool = icmp eq i32 %0, 7
br i1 %tobool, label %if.else, label %if.then
if.else: ; preds = %entry
%1 = sub nsw i32 %0, 7
br label %if.end
if.then: ; preds = %entry
%2 = add nsw i32 %0, 2
br label %if.end
if.end: ; preds = %if.else, %if.then
%result = phi i32 [ %2, %if.then ], [ %1, %if.else ]
ret i32 %result
}
Compiling it (patmos-llc main.s -filetype=obj -o main.o
) and then inspecting the code (patmos-llvm-objdump main.o -d
) will give the following:
.text:
0: 00 00 00 38 li $r0 = 56
main:
4: 87 c2 00 00 00 00 00 00 li $r1 = 0
c: 02 82 11 00 lwc $r1 = [$r1]
10: 02 44 00 30 mfs $r2 = $s0
14: 02 02 13 e1 cmpneq $p1 = $r1, 7
18: 0c 80 00 00 ( $p1) brnd 0
1c: 06 40 00 00 ret
20: 00 40 00 00 nop
24: 00 42 10 07 sub $r1 = $r1, 7
28: 02 40 20 20 mts $s0 = $r2
.LBB0_2:
2c: 06 40 00 00 ret
30: 00 40 00 00 nop
34: 00 02 10 02 add $r1 = $r1, 2
38: 02 40 20 20 mts $s0 = $r2
Notice how the first instruction in main
is at address 4. This is wrong, as the default subfunction alignment is 16 (since we have not specified the alignment using -mpatmos-subfunction-align
).
Trying other alignments, and trying to make additional subfunctions by using -mpatmos-max-subfunction-size
, gives the same results: the alignment is ignored and always set to a 4 byte boundary.
This issue does not appear if we output assembly (patmos-llc main.s -mpatmos-subfunction-align=8
). the alignment assigned to the function will be correct:
.file "main.s"
.text
.globl main
.align 8
.type main,@function
.fstart main, .Ltmp0-main, 8
main: # @main
# BB#0: # %entry
li $r1 = _7
lwc $r1 = [$r1]
mfs $r2 = $s0
cmpneq $p1 = $r1, 7
( $p1) brnd .LBB0_2
# BB#1: # %if.else
ret
nop
sub $r1 = $r1, 7
mts $s0 = $r2
.LBB0_2: # %if.then
ret
nop
add $r1 = $r1, 2
mts $s0 = $r2
.Ltmp0:
.Ltmp1:
.size main, .Ltmp1-main
.type _7,@object # @_7
.data
.globl _7
.align 4
_7:
.word 7 # 0x7
.size _7, 4
Take the following program (main.c
):
volatile int _1 = 1;
int init_func(int iteration_count){
int x = 0;
for(int i = 0; i<iteration_count; i++){
x += i + _1;
}
return x;
}
Notice how the loop is not bounded using _Pragma("loopbound min 0 max 100")
. Compiling this program using the singlepath flag (patmos-clang main.c -Xllc -mpatmos-singlepath=init_func
) will successfully compile and run, even though singlepath code cannot be created for unbounded loops.
Looking at the produced assembly (relevant part):
li $r4 = _1
li $r2 = -1
mfs $r9 = $s0
sws [3] = $r9 # 4-byte Folded Spill
sws [4] = $r26 # 4-byte Folded Spill
pmov $p2 = $p0
.LBB0_1: # %for.cond
# =>This Inner Loop Header: Depth=1
( $p2) add $r2 = $r2, 1
( $p2) cmple $p1 = $r3, $r2
pand $p3 = $p2, !$p1
( $p3) lwc $r6 = [$r4]
( $p2) pmov $p2 = !$p1
( $p3) add $r6 = $r5, $r6
( $p2) br .LBB0_1
( $p3) add $r1 = $r1, $r6
( $p3) add $r5 = $r5, 1
We can see that this loop will run the exact number of times needed and doesn't have an upper bound.
If we bound the above program and look at the assembly:
pmov $p2 = $p0
mov $r5 = $r0
mov $r1 = $r0
li $r4 = _1
li $r2 = -1
li $r26 = 101
sws [0] = $r26
.LBB0_1: # %for.cond
# =>This Inner Loop Header: Depth=1
( $p2) add $r2 = $r2, 1 # Loop bound: [0, 100]
( $p2) cmple $p1 = $r3, $r2
pand $p3 = $p2, !$p1
( $p3) lwc $r6 = [$r4]
( $p2) pmov $p2 = !$p1
( $p3) add $r6 = $r5, $r6
( $p3) add $r1 = $r1, $r6
sub $r26 = $r26, 1
cmplt $p7 = $r0, $r26
( $p7) br .LBB0_1
sws [0] = $r26
( $p3) add $r5 = $r5, 1
We can see that the code is now bounded by 100. This is the only correct way to do singlepath code.
LLVM should be updated to refuse to compile unbounded loops if the mpatmos-singlepath
flag is set.
patmos-clang
refuses to bundle two immediate adds, where the second add's immediate is a label.
Take the following assembly program (we'll call it main.s
):
.globl main
main:
{ add $r4 = $r0, 0
add $r4 = $r0, _1 }
_1:
Trying to compile this program using the command patmos-clang main.s
results in the error:
main.s:4:6: error: the bundle consists of too many instructions
add $r4 = $r0, _1 }
We can work around this error by changing the order of the adds:
.globl main
main:
{ add $r4 = $r0, _1
add $r4 = $r0, 0 }
_1:
Looking at an objectdump of the resulting main.o
we get:
main:
....
52034: 80 08 07 50 { li $r4 = 1872
52038: 00 08 00 00 clr $r4 }
....
Which is exactly the same as our code, since li
and clr
are the pseudo instructions equal to the adds. Running the code in pasim
also executes successfully.
Therefore, we know that the compiler produces two 32-bit instructions. Their order should not matter, which means the original code should also compile.
The error could be caused by the compiler using a long immediate add if it sees the labeled add before the other add. Should this be the case, the compiler should be updated to use the short immediate format when possible, as it is in this case.
Some new dependency break the build under macOS:
/Users/martin/t-crest/llvm/lib/Target/Patmos/SinglePath/SPScope.h:29:10: fatal error:
'boost/optional.hpp' file not found
#include "boost/optional.hpp"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.