Skip to content
Snippets Groups Projects
Commit 069ae70d authored by Alessandro Di Federico's avatar Alessandro Di Federico
Browse files

Fix handling of devirtualized calls

When we have an indirect call (or jump) we are sometimes able to
identify one or more possible targets, therefore, as an optimization,
before performing the indirect jump we check if the target is one of the
expected ones.

This optimization however was creating two issues with the handling of
indirect function calls: 1) the call to the `function_call` marker was
no longer positioned right before the terminator and 2) the function
call was no longer identified as an indirect function call but as call
to `anyPC`. This commit fixes these two issues.

These issues have been identified thanks to a report from Andrea
Gussoni.
parent f6b869bd
No related branches found
No related tags found
No related merge requests found
...@@ -192,17 +192,21 @@ bool FunctionCallIdentification::runOnFunction(llvm::Function &F) { ...@@ -192,17 +192,21 @@ bool FunctionCallIdentification::runOnFunction(llvm::Function &F) {
} else if (SuccessorsCount == 1) { } else if (SuccessorsCount == 1) {
Callee = BlockAddress::get(Terminator->getSuccessor(0)); Callee = BlockAddress::get(Terminator->getSuccessor(0));
} else { } else {
// If there are multiple successors, register the one that is not a // If there are multiple successors, at least one should not be a jump
// jump target // target
bool Found = false;
for (BasicBlock *Successor : successors(Terminator->getParent())) { for (BasicBlock *Successor : successors(Terminator->getParent())) {
if (!GCBI.isJumpTarget(Successor)) { if (!GCBI.isJumpTarget(Successor)) {
// There should be only one non-jump target successor (i.e., anypc // There should be only one non-jump target successor (i.e., anypc
// or unepxectedpc). // or unepxectedpc).
assert(Callee == nullptr); assert(!Found);
Callee = BlockAddress::get(Successor); Found = true;
} }
} }
assert(Callee != nullptr); assert(Found);
// It's an indirect call
Callee = ConstantPointerNull::get(Int8PtrTy);
} }
const std::initializer_list<Value *> Args { const std::initializer_list<Value *> Args {
......
...@@ -133,6 +133,22 @@ bool TranslateDirectBranchesPass::pinJTs(Function &F) { ...@@ -133,6 +133,22 @@ bool TranslateDirectBranchesPass::pinJTs(Function &F) {
Switch->addCase(C(Destination), JTM->getBlockAt(Destination)); Switch->addCase(C(Destination), JTM->getBlockAt(Destination));
} }
// Move all the markers right before the branch instruction
Instruction *Last = BB->getTerminator();
auto It = CallExitTB->getIterator();
while (isMarker(&*It)) {
// Get the marker instructions
Instruction *I = &*It;
// Move the iterator back
It--;
// Move the last moved instruction (initially the terminator)
I->moveBefore(Last);
Last = I;
}
// Notify new branches only if the amount of possible targets actually // Notify new branches only if the amount of possible targets actually
// increased // increased
if (Destinations.size() > OldTargetsCount) if (Destinations.size() > OldTargetsCount)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment