PIC16 now has clang and llc based system to generate native assembly. We then use our native assembler (gpasm) and the native linker (mplink) to generate the final executable. How can I integrate these things with the driver llvmc to have gcc like user experience? Note that we also want to run llvm-ld in order to perform the LTOs in case of multiple files. - Sanjiv
Hi Sanjiv, Sanjiv Gupta <sanjiv.gupta <at> microchip.com> writes:> > PIC16 now has clang and llc based system to generate native assembly. We > then use our native assembler (gpasm) and the native linker (mplink) to > generate the final executable. How can I integrate these things with > the driver llvmc to have gcc like user experience? Note that we also > want to run llvm-ld in order to perform the LTOs in case of multiple files. > > - Sanjiv >You can start with writing a separate llvmc-based driver, say, llvmc-pic16, that uses your custom toolchain. The documentation and examples (especially examples/Skeleton) should get you started. Once you get this working, I can integrate your changes into mainline llvmc. I'll be happy to answer any further questions you may have, feel free to e-mail me directly (though right now our mail server is down).
> I'll be happy to answer any further questions you may have, feel free to e-mail > me directly (though right now our mail server is down) >The salient features that we want to have in the driver are: 1. llvm-ld will be used as "The Optimizer". 2. If the user has specified to generate the final executable, then llvm-ld should run on all the .bc files generated by clang and create a single optimized .bc file for further tools. 3. -Wo <options> - pass optimizations to the llvm-ld 4. mcc16 -Wl <options> - pass options to native linker. 5. mcc16 -Wa <options> - pass options to native assembler. Here are some example command lines and sample command invocations as to what should be done. $ mcc16 -S foo.c // [clang-cc foo.c] -> foo.bc // [llvm-ld foo.bc] -> foo.opt.bc // [llc foo.opt.bc] -> foo.s $ mcc16 -S foo.c bar.c // [clang-cc foo.c] -> foo.bc // [llvm-ld foo.bc] -> foo.opt.bc // [llc foo.opt.bc] -> foo.s // [clang-cc bar.c] -> bar.bc // [llvm-ld bar.bc] -> bar.opt.bc // [llc bar.opt.bc] -> bar.s ** Use of -g causes llvm-ld to run with -disable-opt $ mcc16 -S -g foo.c // [clang-cc foo.c] -> foo.bc // [llvm-ld -disable-opt foo.bc] -> foo.opt.bc // [llc foo.opt.bc] -> foo.s ** -I is passed to clang-cc, -pre-RA-sched=list-burr to llc. $ mcc16 -S -g -I ../include -pre-RA-sched=list-burr foo.c // [clang-cc -I ../include foo.c] -> foo.bc // [llvm-ld -disable-opt foo.bc] -> foo.opt.bc // [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s ** -Wo passes options to llvm-ld $ mcc16 -Wo=opt1,opt2 -S -I ../include -pre-RA-sched=list-burr foo.c // [clang-cc -I ../include foo.c] -> foo.bc // [llvm-ld -opt1 -opt2 foo.bc] -> foo.opt.bc // [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s ** -Wa passes options to native as. $ mcc16 -c foo.c -Wa=opt1 // [clang-cc foo.c] -> foo.bc // [llvm-ld foo.bc] -> foo.opt.bc // [llc foo.opt.bc] -> foo.s // [native-as -opt1 foo.s] -> foo.o $ mcc16 -Wo=opt1 -Wl=opt2 -Wa=opt3 foo.c bar.c // [clang-cc foo.c] -> foo.bc // [clang-cc bar.c] -> bar.bc // [llvm-ld -opt1 foo.bc bar.bc] -> a.out.bc // [llc a.out.bc] -> a.out.s // [native-as -opt3 a.out.s] -> a.out.o // [native-ld -opt2 a.out.o] -> a.out Is this achievable by a tablegen based driver ? - Sanjiv