From 8331f6b3cc71c5fb49433b472bed5c0769788f8b Mon Sep 17 00:00:00 2001 From: Dani Messerman Date: Thu, 30 Apr 2015 23:50:41 +0300 Subject: [PATCH] Added TBAA --- src/binary_translation/CMakeLists.txt | 2 ++ src/binary_translation/Instructions/Types.h | 7 ++++- src/binary_translation/MachineState.cpp | 5 +++- src/binary_translation/ModuleGen.cpp | 3 ++ src/binary_translation/ModuleGen.h | 3 ++ src/binary_translation/TBAA.cpp | 33 +++++++++++++++++++++ src/binary_translation/TBAA.h | 28 +++++++++++++++++ 7 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/binary_translation/TBAA.cpp create mode 100644 src/binary_translation/TBAA.h diff --git a/src/binary_translation/CMakeLists.txt b/src/binary_translation/CMakeLists.txt index 04379bb0c..8b98d2511 100644 --- a/src/binary_translation/CMakeLists.txt +++ b/src/binary_translation/CMakeLists.txt @@ -5,6 +5,7 @@ set(SRCS Disassembler.cpp InstructionBlock.cpp MachineState.cpp + TBAA.cpp Instructions/Instruction.cpp Instructions/DataProcessing.cpp @@ -15,6 +16,7 @@ set(HEADERS Disassembler.h InstructionBlock.h MachineState.h + TBAA.h Instructions/Types.h Instructions/Instruction.h diff --git a/src/binary_translation/Instructions/Types.h b/src/binary_translation/Instructions/Types.h index d9a272b5d..365ef70df 100644 --- a/src/binary_translation/Instructions/Types.h +++ b/src/binary_translation/Instructions/Types.h @@ -1,3 +1,5 @@ +#pragma once + /* * A register in a broad sense: R0-R15, and flags */ @@ -5,9 +7,12 @@ enum class Register { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, SP, LR, PC, - N, Z, C, V + N, Z, C, V, + Count }; +static const size_t RegisterCount = static_cast(Register::Count); + enum class Condition { EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, Invalid diff --git a/src/binary_translation/MachineState.cpp b/src/binary_translation/MachineState.cpp index e992dc1d5..a63b29711 100644 --- a/src/binary_translation/MachineState.cpp +++ b/src/binary_translation/MachineState.cpp @@ -26,13 +26,15 @@ void MachineState::GenerateGlobals() Value* MachineState::ReadRegiser(Register reg) { - auto load = module->IrBuilder()->CreateLoad(GetRegisterPtr(reg)); + auto load = module->IrBuilder()->CreateAlignedLoad(GetRegisterPtr(reg), 4); + module->GetTBAA()->TagRegister(load, reg); return load; } Value* MachineState::WriteRegiser(Register reg, Value *value) { auto store = module->IrBuilder()->CreateAlignedStore(value, GetRegisterPtr(reg), 4); + module->GetTBAA()->TagRegister(store, reg); return store; } @@ -51,5 +53,6 @@ Value *MachineState::GetRegisterPtr(Register reg) index = static_cast(reg)-static_cast(Register::N); } auto base = module->IrBuilder()->CreateAlignedLoad(global, 4); + module->GetTBAA()->TagConst(base); return module->IrBuilder()->CreateConstInBoundsGEP1_32(base, index); } \ No newline at end of file diff --git a/src/binary_translation/ModuleGen.cpp b/src/binary_translation/ModuleGen.cpp index 4a4efb296..a5a31ab82 100644 --- a/src/binary_translation/ModuleGen.cpp +++ b/src/binary_translation/ModuleGen.cpp @@ -17,6 +17,7 @@ ModuleGen::ModuleGen(llvm::Module* module) { ir_builder = make_unique>(getGlobalContext()); machine = make_unique(this); + tbaa = make_unique(); } ModuleGen::~ModuleGen() @@ -25,6 +26,7 @@ ModuleGen::~ModuleGen() void ModuleGen::Run() { + tbaa->GenerateTags(); GenerateGlobals(); DecodeInstructions(); @@ -133,6 +135,7 @@ void ModuleGen::GenerateGetBlockAddressFunction() ir_builder->SetInsertPoint(index_in_bounds_basic_block); Value *gep_values[] = { ir_builder->getInt32(0), index }; auto block_address = ir_builder->CreateLoad(ir_builder->CreateInBoundsGEP(block_address_array, gep_values)); + tbaa->TagConst(block_address); ir_builder->CreateRet(block_address); ir_builder->SetInsertPoint(index_out_of_bounds_basic_block); diff --git a/src/binary_translation/ModuleGen.h b/src/binary_translation/ModuleGen.h index fa94e1784..34419be01 100644 --- a/src/binary_translation/ModuleGen.h +++ b/src/binary_translation/ModuleGen.h @@ -1,6 +1,7 @@ #include #include #include +#include "TBAA.h" enum class Register; @@ -28,6 +29,7 @@ public: llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); } llvm::Module *Module() { return module; } MachineState *Machine() { return machine.get(); } + TBAA *GetTBAA() { return tbaa.get(); } private: // Generates the declarations of all the globals of the module @@ -46,6 +48,7 @@ private: void AddInstructionsToRunFunction(); std::unique_ptr machine; + std::unique_ptr tbaa; std::unique_ptr> ir_builder; llvm::Module *module; diff --git a/src/binary_translation/TBAA.cpp b/src/binary_translation/TBAA.cpp new file mode 100644 index 000000000..b177e99cf --- /dev/null +++ b/src/binary_translation/TBAA.cpp @@ -0,0 +1,33 @@ +#include "TBAA.h" +#include +#include +#include +#include +#include + +using namespace llvm; + +void TBAA::GenerateTags() +{ + MDBuilder md_builder(getGlobalContext()); + + auto tbaa_root = md_builder.createTBAARoot("Root"); + + for (auto i = 0; i < RegisterCount; ++i) + { + std::stringstream ss; + ss << "Register_" << i; + register_nodes[i] = md_builder.createTBAAScalarTypeNode(ss.str(), tbaa_root); + } + const_node = md_builder.createTBAAScalarTypeNode("Readonly", tbaa_root); +} + +void TBAA::TagRegister(Instruction* instruction, Register reg) +{ + instruction->setMetadata(LLVMContext::MD_tbaa, register_nodes[(int)reg]); +} + +void TBAA::TagConst(Instruction* instruction) +{ + instruction->setMetadata(LLVMContext::MD_tbaa, const_node); +} \ No newline at end of file diff --git a/src/binary_translation/TBAA.h b/src/binary_translation/TBAA.h new file mode 100644 index 000000000..d689f98d5 --- /dev/null +++ b/src/binary_translation/TBAA.h @@ -0,0 +1,28 @@ +#include "Instructions/Types.h" + +namespace llvm +{ + class Instruction; + class MDNode; +} + +/* +Manages TBAA. +A TBAA type is generated for each register and global. +It is a bit of an abuse of TBAA but because nothing aliases it is a good way +to notify LLVM of it. +*/ + +class TBAA +{ +public: + void GenerateTags(); + + void TagRegister(llvm::Instruction *instruction, Register reg); + void TagConst(llvm::Instruction *instruction); +private: + llvm::MDNode *register_nodes[RegisterCount]; + // Tag for everything that is never written. + // Since it is never written, one tag works + llvm::MDNode *const_node; +}; \ No newline at end of file