This is my code:
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Instructions.h"
#include "llvm/ADT/BitVector.h"
#include <unordered_map>
#include <queue>
using namespace std;
using namespace llvm;
namespace {
struct LivenessInfo {
BitVector liveIn;
BitVector liveOut;
};
// This method implements what the pass does
void visitor(Function &F){
string func_name = "main";
errs() << "Liveness analysis for function: " << F.getName() << "\n";
// Process each basic block in the function and initialize the live-out and live-in sets
unordered_map<BasicBlock*, LivenessInfo> blockInfo;
BitVector initialLiveOut(F.arg_size() + F.getBasicBlockList().size(), false);
for (auto& basic_block : F) {
LivenessInfo info;
info.liveOut = initialLiveOut;
info.liveIn.resize(F.arg_size() + F.getBasicBlockList().size(), false); // initialize live-in set to
empty
blockInfo[&basic_block] = info;
}
// Creates a worklist of basic blocks to process, starting with the exit block
queue<BasicBlock*> worklist;
auto exitBlock = &F.back();
auto& exitInfo = blockInfo[exitBlock];
worklist.push(exitBlock);
exitInfo.liveOut = BitVector(initialLiveOut.size(), false); // initialize live-out set for exit block to
empty
// Compute the live-out set for each basic block
while (!worklist.empty()) {
auto block = worklist.front();
worklist.pop();
// Compute the live-out set by taking the union of the live-in sets of successors
auto& info = blockInfo[block];
for (auto it = succ_begin(block); it != succ_end(block); ++it) {
auto& succInfo = blockInfo[*it];
info.liveOut |= succInfo.liveIn;
}
// Compute the live-in set based on the live-out set and the instructions in the block
BitVector liveIn(info.liveOut);
for (auto it = block->rbegin(); it != block->rend(); ++it) {
auto inst = &*it;
// Remove variables defined by the instruction from the live-in set
if (auto store = dyn_cast<StoreInst>(inst)) {
auto var = store->getPointerOperand();
size_t varIndex = F.arg_size() + var->getName().substr(1).getAsInteger(10, varIndex);
liveIn.reset(varIndex);
}
// Add variables used by the instruction to the live-in set
for (auto op = inst->op_begin(); op != inst->op_end(); ++op) {
if (auto var = dyn_cast<Instruction>(*op)) {
size_t varIndex = F.arg_size() + var->getName().substr(1).getAsInteger(10, varIndex);
liveIn.set(varIndex);
}
}
}
// Update the live-in set for the current block
info.liveIn = liveIn;
// Add the predecessors of the block to the worklist, if not already processed
for (auto it = pred_begin(block); it != pred_end(block); ++it) {
auto predBlock = *it;
if (blockInfo[predBlock].liveOut != liveIn) {
worklist.push(predBlock);
}
}
}
// Print the live-in and live-out sets for each basic block
for (auto& basic_block : F) {
errs() << "-----" << basic_block.getName() << "-----" << "\n";
auto& info = blockInfo[&basic_block];
errs() << "UEVAR: ";
for (int i = 0; i < F.arg_size(); i++) {
if (inf.
APM Welcome, APM North West Network Conference, Synergies Across Sectors
This is my code- #include -llvm-IR-LegacyPassManager-h- #include -llv.pdf
1. This is my code:
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Instructions.h"
#include "llvm/ADT/BitVector.h"
#include <unordered_map>
#include <queue>
using namespace std;
using namespace llvm;
namespace {
struct LivenessInfo {
BitVector liveIn;
BitVector liveOut;
};
// This method implements what the pass does
void visitor(Function &F){
2. string func_name = "main";
errs() << "Liveness analysis for function: " << F.getName() << "n";
// Process each basic block in the function and initialize the live-out and live-in sets
unordered_map<BasicBlock*, LivenessInfo> blockInfo;
BitVector initialLiveOut(F.arg_size() + F.getBasicBlockList().size(), false);
for (auto& basic_block : F) {
LivenessInfo info;
info.liveOut = initialLiveOut;
info.liveIn.resize(F.arg_size() + F.getBasicBlockList().size(), false); // initialize live-in set to
empty
blockInfo[&basic_block] = info;
}
// Creates a worklist of basic blocks to process, starting with the exit block
queue<BasicBlock*> worklist;
auto exitBlock = &F.back();
auto& exitInfo = blockInfo[exitBlock];
worklist.push(exitBlock);
exitInfo.liveOut = BitVector(initialLiveOut.size(), false); // initialize live-out set for exit block to
empty
// Compute the live-out set for each basic block
3. while (!worklist.empty()) {
auto block = worklist.front();
worklist.pop();
// Compute the live-out set by taking the union of the live-in sets of successors
auto& info = blockInfo[block];
for (auto it = succ_begin(block); it != succ_end(block); ++it) {
auto& succInfo = blockInfo[*it];
info.liveOut |= succInfo.liveIn;
}
// Compute the live-in set based on the live-out set and the instructions in the block
BitVector liveIn(info.liveOut);
for (auto it = block->rbegin(); it != block->rend(); ++it) {
auto inst = &*it;
// Remove variables defined by the instruction from the live-in set
if (auto store = dyn_cast<StoreInst>(inst)) {
auto var = store->getPointerOperand();
size_t varIndex = F.arg_size() + var->getName().substr(1).getAsInteger(10, varIndex);
liveIn.reset(varIndex);
}
// Add variables used by the instruction to the live-in set
for (auto op = inst->op_begin(); op != inst->op_end(); ++op) {
4. if (auto var = dyn_cast<Instruction>(*op)) {
size_t varIndex = F.arg_size() + var->getName().substr(1).getAsInteger(10, varIndex);
liveIn.set(varIndex);
}
}
}
// Update the live-in set for the current block
info.liveIn = liveIn;
// Add the predecessors of the block to the worklist, if not already processed
for (auto it = pred_begin(block); it != pred_end(block); ++it) {
auto predBlock = *it;
if (blockInfo[predBlock].liveOut != liveIn) {
worklist.push(predBlock);
}
}
}
// Print the live-in and live-out sets for each basic block
for (auto& basic_block : F) {
errs() << "-----" << basic_block.getName() << "-----" << "n";
auto& info = blockInfo[&basic_block];
errs() << "UEVAR: ";
5. for (int i = 0; i < F.arg_size(); i++) {
if (info.liveIn[i]) {
auto arg = F.getArg(i);
errs() << arg->getName() << " ";
}
}
errs() << "nVARKILL: ";
for (int i = 0; i < F.arg_size(); i++) {
if (info.liveOut[i] && info.liveIn[i]) {
auto arg = F.getArg(i);
errs() << arg->getName() << " ";
}
}
errs() << "nLIVEOUT: ";
for (int i = 0; i < F.arg_size(); i++) {
if (info.liveOut[i]) {
auto arg = F.getArg(i);
errs() << arg->getName() << " ";
}
}
errs() << "n";
}
}
6. }
struct ValueNumberingPass : public PassInfoMixin<ValueNumberingPass> {
// The first argument of the run() function defines on what level
// of granularity your pass will run (e.g. Module, Function).
// The second argument is the corresponding AnalysisManager
// (e.g ModuleAnalysisManager, FunctionAnalysisManager)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
visitor(F);
return PreservedAnalyses::all();
}
static bool isRequired() { return true; }
};
//-----------------------------------------------------------------------------
// New PM Registration
//-----------------------------------------------------------------------------
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
LLVM_PLUGIN_API_VERSION, "ValueNumberingPass", LLVM_VERSION_STRING,
[](PassBuilder &PB) {
11. LIVEOUT: c e
----- if.else -----
UEVAR: b c
VARKILL: a
LIVEOUT: c e
----- if.end -----
UEVAR: c e
VARKILL: a
LIVEOUT:
What Am I doing wrong?
----- entry -----
UEVAR: b c
VARKILL: e
LIVEOUT: a b c e
----- if.then -----
UEVAR: a
VARKILL: e
LIVEOUT: c e
----- if.else -----
UEVAR: b c
VARKILL: a
LIVEOUT: c e
----- if.end -----