[DLA] Add CreateInterProceduralTypes DLAStep

This commit is contained in:
Pietro Fezzardi
2020-05-07 12:23:09 +02:00
parent 36c89c3118
commit cdee2fb194
4 changed files with 106 additions and 2 deletions
+1
View File
@@ -4,6 +4,7 @@
revng_add_analyses_library(Decompiler revngc
ASTBuildAnalysis.cpp
DLACreateInterProceduralTypes.cpp
DLAHelpers.cpp
DLAPass.cpp
DLAStep.cpp
@@ -0,0 +1,104 @@
//
// Copyright (c) rev.ng Srls. See LICENSE.md for details.
//
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "revng/Support/IRHelpers.h"
#include "DLAStep.h"
#include "DLATypeSystem.h"
using namespace dla;
using namespace llvm;
using StepT = CreateInterproceduralTypes;
bool StepT::runOnTypeSystem(LayoutTypeSystem &TS) {
const Module &M = TS.getModule();
for (const Function &F : M.functions()) {
if (F.isIntrinsic() or not F.getMetadata("revng.func.entry"))
continue;
revng_assert(not F.isVarArg());
// Create the Function's return types
auto FRetTypes = TS.getOrCreateLayoutTypes(F);
// Create types for the Function's arguments
for (const Argument &Arg : F.args()) {
// Arguments can only be integers and pointers
revng_assert(isa<IntegerType>(Arg.getType())
or isa<PointerType>(Arg.getType()));
auto N = TS.getOrCreateLayoutTypes(Arg).size();
// Given that arguments can only be integers or pointers, we should only
// create a single LayoutType for each argument
revng_assert(N == 1ULL);
}
for (const BasicBlock &B : F) {
for (const Instruction &I : B) {
if (auto *Call = dyn_cast<CallInst>(&I)) {
const Function *Callee = getCallee(Call);
if (Callee->isIntrinsic()
or not Callee->getMetadata("revng.func.entry")) {
continue;
}
unsigned ArgNo = 0U;
for (const Argument &FormalArg : Callee->args()) {
Value *ActualArg = Call->getOperand(ArgNo);
revng_assert(isa<IntegerType>(ActualArg->getType())
or isa<PointerType>(ActualArg->getType()));
revng_assert(isa<IntegerType>(FormalArg.getType())
or isa<PointerType>(FormalArg.getType()));
auto ActualTypes = TS.getOrCreateLayoutTypes(*ActualArg);
auto FormalTypes = TS.getOrCreateLayoutTypes(FormalArg);
revng_assert(1ULL == ActualTypes.size() == FormalTypes.size());
auto FieldNum = FormalTypes.size();
for (auto FieldId = 0ULL; FieldId < FieldNum; ++FieldId) {
// Actual type inherits from formal type
TS.addInheritanceLink(ActualTypes[FieldId].first,
FormalTypes[FieldId].first);
}
++ArgNo;
}
} else if (auto *PHI = dyn_cast<PHINode>(&I)) {
revng_assert(isa<IntegerType>(PHI->getType())
or isa<PointerType>(PHI->getType()));
auto PHITypes = TS.getOrCreateLayoutTypes(*PHI);
for (const Use &Incoming : PHI->incoming_values()) {
revng_assert(isa<IntegerType>(Incoming->getType())
or isa<PointerType>(Incoming->getType()));
auto InTypes = TS.getOrCreateLayoutTypes(*Incoming.get());
revng_assert(1ULL == PHITypes.size() == InTypes.size());
auto FieldNum = PHITypes.size();
for (auto FieldId = 0ULL; FieldId < FieldNum; ++FieldId) {
// Incoming type inherits from PHI type
TS.addInheritanceLink(InTypes[FieldId].first,
PHITypes[FieldId].first);
}
}
} else if (auto *RetI = dyn_cast<ReturnInst>(&I)) {
if (Value *RetVal = RetI->getReturnValue()) {
revng_assert(isa<StructType>(RetVal->getType())
or isa<IntegerType>(RetVal->getType())
or isa<PointerType>(RetVal->getType()));
auto RetTypes = TS.getOrCreateLayoutTypes(*RetVal);
revng_assert(RetTypes.size() == FRetTypes.size());
auto FieldNum = RetTypes.size();
for (auto FieldId = 0ULL; FieldId < FieldNum; ++FieldId) {
// Return Operand type inherits from Function return type
if (RetTypes[FieldId].first != nullptr)
TS.addInheritanceLink(RetTypes[FieldId].first,
FRetTypes[FieldId].first);
}
}
}
}
}
}
revng_assert(TS.verifyConsistency());
return TS.getNumLayouts() != 0;
}
-1
View File
@@ -4,7 +4,6 @@
#include "revng-c/Decompiler/DLAPass.h"
// Local includes
#include "DLAStep.h"
#include "DLATypeSystem.h"
+1 -1
View File
@@ -64,7 +64,7 @@ public:
virtual ~CreateInterproceduralTypes() override = default;
virtual bool runOnTypeSystem(LayoutTypeSystem &TS) override { return true; }
virtual bool runOnTypeSystem(LayoutTypeSystem &TS) override;
};
/// dla::Step that creates types for LLVM Values inside Functions and edges