-
Notifications
You must be signed in to change notification settings - Fork 0
/
AddMetadataOnLoop.cpp
123 lines (91 loc) · 3.5 KB
/
AddMetadataOnLoop.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/IR/Dominators.h"
#include <iostream>
#include <string>
// #define DEBUG_MODE
#ifdef DEBUG_MODE
#define myerrs() errs()
#else
#define myerrs() nulls()
#endif
using namespace llvm;
void add_metadata(Module & Mod, Instruction & Inst);
namespace {
struct AddMetadataOnLoop : public ModulePass{
static char ID;
AddMetadataOnLoop() : ModulePass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage& AU) const override;
virtual bool runOnModule(Module &Mod) override;
};//end of struct AddMetadataOnLoop
}//end of anonymous namespace
void AddMetadataOnLoop::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
}
bool AddMetadataOnLoop::runOnModule(Module &Mod){
errs() << "AddMetadataOnLoop: ";
errs().write_escaped(Mod.getName()) << '\n';
for(Function &Func : Mod){
if(! Func.empty ()){
//Call LoopInfoWrapperPass to get the Loop in current Function
//Call DominatorTreeWrapperPass to get the back edge infomation
LoopInfo* LI = &getAnalysis<LoopInfoWrapperPass>(Func).getLoopInfo();
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>(Func).getDomTree();
for(Loop* loop : LI->getLoopsInPreorder()){
myerrs() << "*** Add Metadata On Loop ***\n";
for(BasicBlock * blk : loop->getBlocks () ){
for(Instruction & inst : *blk){
// Check whether a br instruction represents back edge for current loop
// Add metadata if it is.
if (llvm::BranchInst* br = dyn_cast<llvm::BranchInst>(&inst)){
BasicBlock * current_block = br->getParent();
for(unsigned i = 0; i < br->getNumSuccessors(); i++){
BasicBlock * successor_block = br->getSuccessor(i);
bool is_backedge = DT->dominates(successor_block, current_block);
if(is_backedge){
add_metadata(Mod, inst);
}
}
}
}
}
}
}
}
return false;
}
char AddMetadataOnLoop::ID = 0;
/*Register to "opt" */
static RegisterPass<AddMetadataOnLoop> X("addmetadataonloop", "Add Metadata On Loop pass", false /* Only looks at CFG */,
false /* Analysis Pass */);
/*
** Add metadata to Instruction inst, which is in Module Mod
*/
void add_metadata(Module & Mod, Instruction & inst){
const std::string & sourcefilename = Mod.getSourceFileName();
std::string filename_line_content="";
const DebugLoc &DL = inst.getDebugLoc();
if(DL.get()){
unsigned line = DL.get()->getLine();
filename_line_content = "sourcefilename: " + sourcefilename + ", line: " + std::to_string(line)+"\00";
}else{
filename_line_content = "sourcefilename: " + sourcefilename + ", line: UNKOWN \00";
}
myerrs() << "filename_line_content: " << filename_line_content << "\n";
LLVMContext& C = inst.getContext();
MDNode* N = MDNode::get(C, MDString::get(C, filename_line_content));
inst.setMetadata("filename_line", N);
}