Giter Site home page Giter Site logo

t-crest / patmos-llvm Goto Github PK

View Code? Open in Web Editor NEW
15.0 15.0 8.0 269.09 MB

Port of the LLVM compiler infrastructure to the time-predictable processor Patmos

License: Other

CMake 0.28% Makefile 0.47% Shell 0.80% C++ 53.90% OCaml 0.38% Python 0.59% C 0.62% Assembly 10.14% HTML 0.01% LLVM 31.64% Perl 0.05% Emacs Lisp 0.02% M4 0.29% Vim Script 0.02% Batchfile 0.01% Ruby 0.78% NASL 0.01%

patmos-llvm's People

Contributors

ahatanak avatar alkis avatar asl avatar atrick avatar bcardosolopes avatar bigcheese avatar bob-wilson avatar chandlerc avatar chapuni avatar cunningbaldrick avatar d0k avatar ddunbar avatar dlp avatar echristo avatar eefriedman avatar espindola avatar ggreif avatar greened avatar isanbard avatar lattner avatar lhames avatar mbrukman avatar nlewycky avatar resistor avatar sampo3k avatar stefanhepp avatar stoklund avatar tkremenek avatar topperc avatar zwarich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

patmos-llvm's Issues

Function splitter accepts inline assembly blocks larger than subfunction size

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.

patmos-clang always links libraries

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.

patmos-clang: cannot bundle two immediate adds in assembly

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.

Endianess set wrong

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

patmos-clang crash

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

Singlepath: crashes on break from nested loop

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)

Remove use of '@code' symbol type for subfunctions

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.

singlepath: singlepath crashes when divide is used and compiled from bitcode

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.

SinglePath/SPScope breaks build on macOS

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"

Singlepath: wrong execution when returning from loop

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.

Handling unresolved calls in PML

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

  1. source code annotations
  2. external annotations

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.

Proposed PMLPath (by example):

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]

Question: multiply takes a different number of cycles based on input

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:

  1. Does the mul actually take a different number of cycles based on input?
  2. Does WCET analysis know about how many cycles the mul will take depending on input?

Singlepath: unbounded loops produce non-singlepath code

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.

Extract Platin into its own repository

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.

assembly: invalid `bcopy` parsing

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"
  );
}

Remove MachineModulePass from LLVM

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.

-mpatmos-subfunction-align flag doesn't seem to work

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

Compile on Mac M1

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

ARM related

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.

Doesn't compile on MacOs

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.