Added TBAA

This commit is contained in:
Dani Messerman 2015-04-30 23:50:41 +03:00
parent d7367172e8
commit 8331f6b3cc
7 changed files with 79 additions and 2 deletions

View File

@ -5,6 +5,7 @@ set(SRCS
Disassembler.cpp Disassembler.cpp
InstructionBlock.cpp InstructionBlock.cpp
MachineState.cpp MachineState.cpp
TBAA.cpp
Instructions/Instruction.cpp Instructions/Instruction.cpp
Instructions/DataProcessing.cpp Instructions/DataProcessing.cpp
@ -15,6 +16,7 @@ set(HEADERS
Disassembler.h Disassembler.h
InstructionBlock.h InstructionBlock.h
MachineState.h MachineState.h
TBAA.h
Instructions/Types.h Instructions/Types.h
Instructions/Instruction.h Instructions/Instruction.h

View File

@ -1,3 +1,5 @@
#pragma once
/* /*
* A register in a broad sense: R0-R15, and flags * 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, R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, SP, LR, PC, R8, R9, R10, R11, R12, SP, LR, PC,
N, Z, C, V N, Z, C, V,
Count
}; };
static const size_t RegisterCount = static_cast<size_t>(Register::Count);
enum class Condition enum class Condition
{ {
EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, Invalid EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, Invalid

View File

@ -26,13 +26,15 @@ void MachineState::GenerateGlobals()
Value* MachineState::ReadRegiser(Register reg) 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; return load;
} }
Value* MachineState::WriteRegiser(Register reg, Value *value) Value* MachineState::WriteRegiser(Register reg, Value *value)
{ {
auto store = module->IrBuilder()->CreateAlignedStore(value, GetRegisterPtr(reg), 4); auto store = module->IrBuilder()->CreateAlignedStore(value, GetRegisterPtr(reg), 4);
module->GetTBAA()->TagRegister(store, reg);
return store; return store;
} }
@ -51,5 +53,6 @@ Value *MachineState::GetRegisterPtr(Register reg)
index = static_cast<unsigned>(reg)-static_cast<unsigned>(Register::N); index = static_cast<unsigned>(reg)-static_cast<unsigned>(Register::N);
} }
auto base = module->IrBuilder()->CreateAlignedLoad(global, 4); auto base = module->IrBuilder()->CreateAlignedLoad(global, 4);
module->GetTBAA()->TagConst(base);
return module->IrBuilder()->CreateConstInBoundsGEP1_32(base, index); return module->IrBuilder()->CreateConstInBoundsGEP1_32(base, index);
} }

View File

@ -17,6 +17,7 @@ ModuleGen::ModuleGen(llvm::Module* module)
{ {
ir_builder = make_unique<IRBuilder<>>(getGlobalContext()); ir_builder = make_unique<IRBuilder<>>(getGlobalContext());
machine = make_unique<MachineState>(this); machine = make_unique<MachineState>(this);
tbaa = make_unique<TBAA>();
} }
ModuleGen::~ModuleGen() ModuleGen::~ModuleGen()
@ -25,6 +26,7 @@ ModuleGen::~ModuleGen()
void ModuleGen::Run() void ModuleGen::Run()
{ {
tbaa->GenerateTags();
GenerateGlobals(); GenerateGlobals();
DecodeInstructions(); DecodeInstructions();
@ -133,6 +135,7 @@ void ModuleGen::GenerateGetBlockAddressFunction()
ir_builder->SetInsertPoint(index_in_bounds_basic_block); ir_builder->SetInsertPoint(index_in_bounds_basic_block);
Value *gep_values[] = { ir_builder->getInt32(0), index }; Value *gep_values[] = { ir_builder->getInt32(0), index };
auto block_address = ir_builder->CreateLoad(ir_builder->CreateInBoundsGEP(block_address_array, gep_values)); 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->CreateRet(block_address);
ir_builder->SetInsertPoint(index_out_of_bounds_basic_block); ir_builder->SetInsertPoint(index_out_of_bounds_basic_block);

View File

@ -1,6 +1,7 @@
#include <llvm/IR/IRBuilder.h> #include <llvm/IR/IRBuilder.h>
#include <unordered_map> #include <unordered_map>
#include <common/common_types.h> #include <common/common_types.h>
#include "TBAA.h"
enum class Register; enum class Register;
@ -28,6 +29,7 @@ public:
llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); } llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); }
llvm::Module *Module() { return module; } llvm::Module *Module() { return module; }
MachineState *Machine() { return machine.get(); } MachineState *Machine() { return machine.get(); }
TBAA *GetTBAA() { return tbaa.get(); }
private: private:
// Generates the declarations of all the globals of the module // Generates the declarations of all the globals of the module
@ -46,6 +48,7 @@ private:
void AddInstructionsToRunFunction(); void AddInstructionsToRunFunction();
std::unique_ptr<MachineState> machine; std::unique_ptr<MachineState> machine;
std::unique_ptr<TBAA> tbaa;
std::unique_ptr<llvm::IRBuilder<>> ir_builder; std::unique_ptr<llvm::IRBuilder<>> ir_builder;
llvm::Module *module; llvm::Module *module;

View File

@ -0,0 +1,33 @@
#include "TBAA.h"
#include <llvm/IR/MDBuilder.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Metadata.h>
#include <sstream>
#include <llvm/IR/Instruction.h>
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);
}

View File

@ -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;
};