-
Notifications
You must be signed in to change notification settings - Fork 1
/
pyllco_helper.cpp
46 lines (41 loc) · 2.09 KB
/
pyllco_helper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// SPDX-FileCopyrightText: 2020 Gerion Entrup <[email protected]>
// SPDX-FileCopyrightText: 2021 Gerion Entrup <[email protected]>
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "pyllco_helper.h"
namespace pyllco {
std::string get_subclass(const llvm::Value& v) {
// this is getting a little big ugly but the only possibility to circumvent
// LLVM's strange handmade RTTI.
//
// This RTTI stores in every (child) object an additional number to indicate the type. Therefore the super class
// needs to know all number in advance. This is mainly done with the ValueTy enum in Value.h. This enum is not
// hardcoded but includes a special header Value.def. We can use this header as well to reverse the process.
// Unfortunately, Instructions are handled separate. The concept of one unique number per subclass is broken. It
// is one unique number per Opcode. This is done in another special header "Instruction.def". See
// "Instruction.h" and "InstVisitor.h" for its regular usage. We can use this header as well.
switch (v.getValueID()) {
#define HANDLE_VALUE(Name) \
case llvm::Value::Name##Val: \
return #Name;
#include <llvm/IR/Value.def>
#define HANDLE_INST(N, Opcode, Class) \
case llvm::Value::InstructionVal + llvm::Instruction::Opcode: \
return #Class;
#include <llvm/IR/Instruction.def>
}
assert(false);
// make the compiler happy
return "";
}
bool get_gep_offset(const llvm::GetElementPtrInst& gep, int64_t& offset) {
const auto layout = gep.getModule()->getDataLayout();
llvm::APInt ap_offset(layout.getIndexSizeInBits(gep.getPointerAddressSpace()), 0, true);
bool success = gep.accumulateConstantOffset(layout, ap_offset);
if (!success) {
return false;
}
offset = ap_offset.getSExtValue();
return true;
}
} // namespace pyllco