Files
revng-revng/include/revng/UnitTestHelpers/LLVMTestHelpers.h
2020-11-13 14:12:18 +01:00

95 lines
2.3 KiB
C++

#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "llvm/IR/Instructions.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/SourceMgr.h"
#include "revng/Support/Assert.h"
static const char *ModuleBegin = R"LLVM(
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@rax = internal global i64 0
@rdi = internal global i64 0
@rsi = internal global i64 0
@rbx = internal global i64 0
@rcx = internal global i64 0
@pc = internal global i64 0
declare i64 @llvm.bswap.i64(i64)
define void @main() {
initial_block:
)LLVM";
static const char *ModuleEnd = R"LLVM(
}
)LLVM";
inline std::string buildModule(const char *Body) {
std::string Result;
Result += ModuleBegin;
Result += Body;
Result += ModuleEnd;
return Result;
}
inline llvm::Instruction *
instructionByName(llvm::Function *F, const char *Name) {
using namespace llvm;
if (StringRef(Name).startswith("s:")) {
Name = Name + 2;
for (BasicBlock &BB : *F)
for (Instruction &I : BB)
if (auto *Store = dyn_cast<StoreInst>(&I))
if (Store->getValueOperand()->hasName()
and Store->getValueOperand()->getName() == Name)
return &I;
} else {
for (BasicBlock &BB : *F)
for (Instruction &I : BB)
if (I.hasName() and I.getName() == Name)
return &I;
}
revng_abort("Couldn't find a Value with the requested name");
}
inline llvm::BasicBlock *basicBlockByName(llvm::Function *F, const char *Name) {
revng_assert(F != nullptr);
for (llvm::BasicBlock &BB : *F)
if (BB.hasName() and BB.getName() == Name)
return &BB;
revng_abort("Couldn't find a Value with the requested name");
}
inline std::unique_ptr<llvm::Module>
loadModule(llvm::LLVMContext &C, const char *Body) {
using namespace llvm;
std::string ModuleText = buildModule(Body);
SMDiagnostic Diagnostic;
using MB = MemoryBuffer;
std::unique_ptr<MB> Buffer = MB::getMemBuffer(StringRef(ModuleText));
std::unique_ptr<Module> M = parseIR(Buffer.get()->getMemBufferRef(),
Diagnostic,
C);
if (M.get() == nullptr) {
Diagnostic.print("revng", dbgs());
revng_abort();
}
return M;
}