Fixed emission for local_sp and scev_barrier

This commit fixes a bug due to interacting behaviors between
MarkForSerialization, AddSCEVBarrierPass, and the emission in C of calls
to revng_init_local_sp.

These interacting behaviors caused the following quirks:
- At the beginning of Functions that contained a call to
  `revng_init_local_sp()`, that call was actually emitted twice.
  The first time was due to the actual call to `revng_init_local_sp()`,
  while the second was due to the first call being wrapped from a call
  to `revng_scev_barrier_*`.
  Now we properly emit only one call.
- The original call to `revng_init_local_sp()` was supposed to generate
  a local variable, to be used in various places across the function.
  However, due to the fact that the call was not properly labeled by
  MarkForSerialization, there was no local variable, causing calls to
  `revng_init_local_sp()` to be scattered around the body of the
  functions, follwed by various arithmetic operations.
  This behavior has been fixed as well, and we now emit the local
  variable correctly.
This commit is contained in:
Pietro Fezzardi
2021-01-14 14:28:14 +01:00
parent ba0e57e956
commit 4767fa63c3
3 changed files with 27 additions and 6 deletions
+11 -2
View File
@@ -102,9 +102,20 @@ Analysis::InterruptType Analysis::transfer(const llvm::BasicBlock *BB) {
// StoreInst and CallInst that are not pure always have side effects.
ToSerialize[&I].set(HasSideEffects);
revng_log(MarkLog, "Instr HasSideEffects");
// Also, force calls to revng_init_local_sp to behave like if they had
// many uses, so that they generate a local variable.
if (auto *Call = dyn_cast<CallInst>(&I)) {
llvm::StringRef CalleeName = Call->getCalledFunction()->getName();
if (CalleeName == "revng_init_local_sp") {
ToSerialize[&I].set(HasManyUses);
revng_log(MarkLog, "Instr HasManyUses");
}
}
}
switch (I.getNumUses()) {
case 1: {
User *U = I.uses().begin()->getUser();
Instruction *UserI = cast<Instruction>(U);
@@ -113,8 +124,6 @@ Analysis::InterruptType Analysis::transfer(const llvm::BasicBlock *BB) {
if (NBBDuplicates < UserNDuplicates) {
ToSerialize[&I].set(HasDuplicatedUses);
revng_log(MarkLog, "Instr HasDuplicatedUses");
} else {
Pending.insert(&I);
}
} break;