In LLVM, how can I have generate a branch instruction that jumps directly, rather than having if-else. I know there is LLVM::BranchInst class, but don't know how to use it for this purpose, or do I need to use some other class?
You need an unconditional branch:
static BranchInst * llvm::BranchInst::Create(BasicBlock *IfTrue,
Instruction *InsertBefore = 0)
static BranchInst * llvm::BranchInst::Create(BasicBlock *IfTrue,
BasicBlock *InsertAtEnd)
Use this method:
static BranchInst * Create (BasicBlock *IfTrue, BasicBlock *InsertAtEnd)
The first argument is where you are jumping to and the second one is where created instruction should be placed.
Related
This is the beginning of a function that already exists and works; the commented line is my addition and its purpose is to toggle a pin.
inline __attribute__((naked))
void CScheduler::SwapToThread(void* pNew, void* pPrev)
{
//*(volatile DWORD*)0x400FF08C = (1 << 14);
if (pPrev != NULL)
{
if (pPrev == this) // Special case to save scheduler stack on startup
{
asm("mov lr,%0"::"p"(&CScheduler_Run_Exit)); // load r1 with schedulers End thread
asm("orr lr, 1");
When I uncomment my addition, my hard fault handler executes. I get it has something to do with this being a naked function but I don't understand why a simple assignment causes a problem.
Two questions:
Why does this line trigger the hard fault?
How can I perform this assignment inside this function?
It was only luck that your previous version of the function happened to work without crashing.
The only thing that can safely be put inside a naked function is a pure Basic Asm statement. https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html. You can split it up into multiple Basic Asm statements, instead of asm("insn \n\t" / "insn2 \n\t" / ...);, but you have to write the entire function in asm yourself.
While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.
If you want to run C++ code from a naked function, you could call a regular function (or bl on ARM, jal on MIPS, etc.), following to the standard calling convention.
As for the specific reason in this case? Maybe creating that address in a register stepped on the function args, leading to the branches going wrong? Inspect the generated asm if you want, but it's 100% unsupported.
Or maybe it ended up using more registers, and since it's naked didn't properly save/restore call-preserved registers? I haven't looked at the code-gen myself for naked functions.
Are you sure this function needs to be naked? I guess that's because you manipulate lr to return to the new context.
If you don't want to just write more logic in asm, maybe have this function's caller do more work (and maybe pass it pointer and/or boolean args telling it more simply what it needs to do, so your inputs are already in registers, and you don't need to access globals).
Does LLVM support for branch instructions with a variable BasicBlock target?
More specifically, suppose I convert all unconditional br instructions into function calls to some function f. Is it then possible to provide the target label as an argument to f, and then use this label in an unconditional branch within f?
Or is the only solution to make a switch in f, map all BB's to unique ID's, and then call f with the ID corresponding to the target BB?
From what I can see, non-local indirect branches to labels aren't possible.
http://blog.llvm.org/2010/01/address-of-label-and-indirect-branches.html?m=1
I want to know if an llvm::intruction is a function call and if so what is the name of the fucntion it is calling to.
Also is there a way to get llvm::CallInst from an llvm::Instruction?
Instruction* I = ...
if (isa<CallInst>(I)) {
StringRef name = cast<CallInst>(I).getCalledFunction().getName();
...
}
For more information on this, see the relevant section in LLVM Programmer's Manual. In general, I wholeheartedly recommend this guide for beginners.
Instruction is the common base class for all LLVM instructions.
CallInst is a subclass of Instruction for call instructions.
If you have Instruction *inst, you can get a CallInst by
CallInst *ci = cast<CallInst>(inst);
Following up on this question, is it possible for llvm to generate code that may jump to an arbitrary address within a function in the same address space?
i.e.
void func1() {
...
<code that jumps to addr2>
...
}
void func2() {
...
addr2:
<some code in func2()>
...
}
Yes,No,Yes,No,(yes) - It depends on the level you look at and what you mean with possible:
Yes, as the llvm backend will produce target specific assembler
instructions and those assembler instructions allow to set the
program counter to an abitrary value.
No, because - as far as I know - the llvm ir (the intermediate representation into which a frontend like clang compiles your c code) hasn't any instructions that would allow abitrary jumps between (llvm-ir) functions.
Yes, because the frontend COULD certainly produce code, that simulates that behaviour (breaking up func2 into multiple separate functions).
No, because C and C++ don't allow such jumps to ARBITRARY positions and so clang will not compile any program that tries to do that (e.g. via goto)
(yes) the c longjmp macro jumps back to a place in the control flow that you have already visited (where you called setjmp) but also restores (most) of the system state. EDIT: However, this is UB if func2 isn't somewhere up in the current callstack from where you jump.
I am working on converting another IR to llvm IR.
My IR is like this:
a = 1;
b = a;
a = a + 1;
For now, I am using alloca to create variable in my IR (Here for "a" and "b").
However, alloca probably is too heavy, it will introduce lots of load store instructions. This will be a problem if the function is huge. Actually, for my case, most of the variables are register-width. So I just want them be a virtual register with name.
Anybody know how to create a virtual register(variable) instead of memory variable?
I mean how to avoid using "alloca"?
You are not supposed to. Generating SSA code is a quite hard problem, so it's solved once for all frontends in LLVM passes. You are supposed to use alloca and load/store, and then run the mem2reg pass to convert those into SSA variables. Clang also does this (stick your example code in a C function, and compile it with no optimizations).