source: icGREP/icgrep-devel/icgrep/IR_Gen/tracegen.h @ 5269

Last change on this file since 5269 was 5269, checked in by cameron, 2 years ago

Tracing tool

File size: 4.3 KB
Line 
1/*
2 *  Copyright (c) 2017 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5#ifndef TRACEGEN_H
6#define TRACEGEN_H
7
8#include "idisa_builder.h"
9#include <string>
10#include <llvm/IR/Module.h>
11#include <llvm/IR/Constants.h>
12#include <llvm/IR/Intrinsics.h>
13#include <llvm/IR/Function.h>
14
15
16
17class TraceTool {
18public:
19    TraceTool(IDISA::IDISA_Builder * b, unsigned log2TraceBufSize = 16);
20   
21    unsigned declareTraceVar(std::string traceVarName);
22   
23    unsigned newTraceVar(std::string traceName);
24    void addTraceEntry(unsigned traceVar, llvm::Value * traceVal);
25    void createDumpTrace();
26   
27private:
28    IDISA::IDISA_Builder * iBuilder;
29    unsigned mLog2TraceBufSize;
30    unsigned mTraceVarCount;
31    std::vector<llvm::Value *> mTraceFormatString;
32    llvm::Value * mTraceBufferPtr;
33    llvm::Value * mTraceIndexPtr;
34    llvm::Constant * mTraceIndexMask;
35};
36
37using namespace llvm;
38
39TraceTool::TraceTool(IDISA::IDISA_Builder * b, unsigned log2TraceBufSize) :
40    iBuilder(b),
41    mLog2TraceBufSize(log2TraceBufSize),
42    mTraceVarCount(0) {
43
44    Type * entryType = StructType::get(iBuilder->getInt8Ty()->getPointerTo(), iBuilder->getSizeTy(), nullptr);
45    Type * bufferType = ArrayType::get(entryType, 1 << mLog2TraceBufSize);
46    mTraceBufferPtr = iBuilder->CreateAlloca(bufferType);
47    mTraceIndexPtr = iBuilder->CreateAlloca(iBuilder->getInt32Ty());
48    iBuilder->CreateStore(ConstantInt::getNullValue(iBuilder->getInt32Ty()), mTraceIndexPtr);
49    mTraceIndexMask = ConstantInt::get(iBuilder->getInt32Ty(), (1 << mLog2TraceBufSize) - 1);
50}
51
52unsigned TraceTool::newTraceVar(std::string traceName) {
53    std::string formatString = traceName + " = %" PRIx64 "\n";
54    mTraceFormatString.push_back(iBuilder->CreateGlobalStringPtr(formatString.c_str()));
55    return mTraceVarCount++;
56}
57
58void TraceTool::addTraceEntry(unsigned traceVar, llvm::Value * traceVal) {
59   
60    Value * traceIndex = iBuilder->CreateLoad(mTraceIndexPtr);
61    Value * entryVarPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), traceIndex, iBuilder->getInt32(0)});
62    iBuilder->CreateStore(mTraceFormatString[traceVar], entryVarPtr);
63    Value * entryValPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), traceIndex, iBuilder->getInt32(1)});
64    iBuilder->CreateStore(iBuilder->CreateZExt(traceVal, iBuilder->getSizeTy()), entryValPtr);
65    iBuilder->CreateStore(iBuilder->CreateAnd(mTraceIndexMask, iBuilder->CreateAdd(traceIndex, iBuilder->getInt32(1))), mTraceIndexPtr);
66}
67
68void TraceTool::createDumpTrace() {
69    Constant * traceBufSize = ConstantInt::get(iBuilder->getInt32Ty(), 1<<mLog2TraceBufSize);
70    Function * printF = iBuilder->GetPrintf();
71    BasicBlock * DumpEntryBlock = iBuilder->GetInsertBlock();
72    Function * currentFn = DumpEntryBlock->getParent();
73    BasicBlock * DumpTraceLoop = BasicBlock::Create(iBuilder->getContext(), "DumpTraceLoop", currentFn, 0);
74    BasicBlock * DumpTraceExit = BasicBlock::Create(iBuilder->getContext(), "DumpTraceExit", currentFn, 0);
75   
76    Value * lastTraceIndex = iBuilder->CreateLoad(mTraceIndexPtr);
77    Value * truncated = iBuilder->CreateICmpUGT(lastTraceIndex, traceBufSize);
78    Value * firstDumpIndex = iBuilder->CreateSelect(truncated, iBuilder->CreateSub(lastTraceIndex, traceBufSize), ConstantInt::getNullValue(iBuilder->getInt32Ty()));
79   
80    iBuilder->CreateBr(DumpTraceLoop);
81    iBuilder->SetInsertPoint(DumpTraceLoop);
82    PHINode * loopIndex = iBuilder->CreatePHI(iBuilder->getInt32Ty(), 2);
83    loopIndex->addIncoming(firstDumpIndex, DumpEntryBlock);
84   
85    Value * entryVarPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), loopIndex, iBuilder->getInt32(0)});
86    Value * formatString = iBuilder->CreateLoad(entryVarPtr);
87    Value * entryValPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), loopIndex, iBuilder->getInt32(1)});
88    Value * entryVal = iBuilder->CreateLoad(entryValPtr);
89    iBuilder->CreateCall(printF, {formatString, entryVal});
90   
91    Value * nextIndex = iBuilder->CreateAnd(iBuilder->CreateAdd(loopIndex, iBuilder->getInt32(1)), mTraceIndexMask);
92    loopIndex->addIncoming(nextIndex, DumpTraceLoop);
93    Value * atLastTraceIndex = iBuilder->CreateICmpEQ(loopIndex, lastTraceIndex);
94    iBuilder->CreateCondBr(atLastTraceIndex, DumpTraceExit, DumpTraceLoop);
95    iBuilder->SetInsertPoint(DumpTraceExit);
96}
97
98#endif
Note: See TracBrowser for help on using the repository browser.