Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modificações accept #1

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Accept/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
ACCEPT_DIR ?= ../../accept
include $(ACCEPT_DIR)/accept.mk
LIBS := -lm -liomp5

SOURCES := pi.c
SOMADOR := addx

BIBLIOTECAS = $(ACCEPT_DIR)/include
NAME := $(basename $(SOURCES))
MOD_NAME := $(addsuffix _modificado.c, $(NAME))
OUTPUT := $(addsuffix _$(SOMADOR), $(NAME))
ARQUIVOS_PARA_REMOVER := $(MOD_NAME) *$(SOMADOR) *.bc *.s

construir_addx:
$(MAKE) limpar
$(MAKE) build_orig OPTARGS="-all-lpe"
nano accept_config.txt
$(MAKE) pause
python $(ACCEPT_DIR)/script.py $(SOMADOR)

ls > temp.txt
if grep -q $(MOD_NAME) temp.txt; then \
riscv32-unknown-elf-gcc $(MOD_NAME) -O1 -march=rv32im -o $(OUTPUT) -lm -I $(BIBLIOTECAS) \
$(eval export PATH=$(PATH):/opt/riscv/bin); \
else \
riscv32-unknown-elf-gcc $(SOURCES) -O1 -march=rv32im -o $(OUTPUT) -lm -I $(BIBLIOTECAS) \
$(eval export PATH=$(PATH):/opt/riscv/bin); \
fi
rm temp.txt

clear
spike --isa=RV32I /opt/riscv/riscv32-unknown-elf/bin/pk $(OUTPUT)


construir_accept:
$(MAKE) limpar
$(MAKE) build_orig OPTARGS="-all-lpe"
nano accept_config.txt
$(MAKE) pause
$(MAKE) build_opt


construir_accept_spike:
$(MAKE) limpar
$(MAKE) construir_accept
/usr/lib/llvm-10/bin/llc -O2 -march=riscv32 -filetype=asm app.opt.bc -o $(NAME).s
riscv32-unknown-elf-gcc $(NAME).s -O1 -march=rv32im -o $(OUTPUT) -lm \
$(eval export PATH=$(PATH):/opt/riscv/bin)
time spike --isa=RV32I /opt/riscv/riscv32-unknown-elf/bin/pk $(OUTPUT) \
$(eval export PATH=$(PATH):/opt/riscv/bin)


pause:
@echo "Modificou accept_config.txt?"
@read dummy

limpar:
$(MAKE) clean
$(foreach arq,$(ARQUIVOS_PARA_REMOVER), \
if [ -n "$(wildcard $(arq))" ]; then rm $(arq); fi; \
)
22 changes: 22 additions & 0 deletions Accept/Pass/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
accept.h:

Foi adicionado uma nova variavel para guardar o valor da escolha da perfuração:
Linha 173: std::map<std::string, int> doIt;


loopperf.cpp

Foi modificado a instrução que decide qual loop sera perfurado considerando o parametro, para tambem considerar o valor de escolha da perfuração.
Linha 132: if (param && (!condi)) {


transform.cpp

Foi adicionado uma nova varialvel '1' no arquivo accept_config.txt que sera a escolha de perfuração, como tambem instruções para ler e salvar essa variavel.
Linha 158: configFile << i->second << " " << "1" << " " << i->first << "\n";
Linha 179: configFile >> var;
Linha 180: configFile.ignore();
Linha 183: doIt[ident] = var;

Após modificar esse arquivos, vá até a pasta do accept: accept/ e executa o seguinte comando:
sudo make accept
260 changes: 260 additions & 0 deletions Accept/Pass/accept.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
#include "llvm/Analysis/Passes.h"
#include "llvm/PassRegistry.h"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/DebugInfo.h"
#include "llvm/Analysis/ProfileInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/IRBuilder.h"

#include <set>
#include <map>
#include <string>
#include <cassert>

#define ECQ_PRECISE 0
#define ECQ_APPROX 1
#define ECQ_APPROX_PTR 2

// Logging macro.
#define ACCEPT_LOG_(d) if (d) *d
#define ACCEPT_LOG ACCEPT_LOG_(desc)


namespace llvm {
ImmutablePass *createAcceptAAPass();
void initializeAcceptAAPass(PassRegistry &Registry);
FunctionPass *createAcceptTransformPass();
extern FunctionPass *sharedAcceptTransformPass;
LoopPass *createLoopParallelizePass();
LoopPass *createLoopPerfPass();
void initializeLoopNPUPass(PassRegistry &Registry);
LoopPass *createLoopNPUPass();
FunctionPass *createFunctionApproxPass();
FunctionPass *createErrorInjectionPass();
void initializeErrorInjectionPass(PassRegistry &Registry);
void initializeApproxInfoPass(PassRegistry &Registry);

std::string srcPosDesc(const Module &mod, const DebugLoc &dl);
std::string instDesc(const Module &mod, const Instruction *inst);
std::string getFilename(const Module &mod, const DebugLoc &dl);

extern bool acceptUseProfile;
}

#define PERMIT "ACCEPT_PERMIT"
#define FORBID "ACCEPT_FORBID"
typedef enum {
markerNone,
markerPermit,
markerForbid
} LineMarker;

// Logging: a section of the ACCEPT log.
class LogDescription {
public:
LogDescription() : text(""), stream(NULL) {}
LogDescription(const LogDescription &d)
: text(d.text), blockers(d.blockers), stream(NULL) {}
void operator=(const LogDescription &d);
~LogDescription();
bool operator==(const LogDescription &rhs);
operator llvm::raw_ostream &();
std::string &getText();
void blocker(int lineno, llvm::StringRef s);
void operator<<(const llvm::Instruction *inst);
std::string text;
std::map< int, std::vector<std::string> > blockers;
llvm::raw_string_ostream *stream;

// The location of a LogDescription for positioning in the log.
class Location {
public:
Location() : kind(""), fileName(""), lineNumber(0) {}
Location(llvm::StringRef myKind,
llvm::StringRef myFile, const int myNum) :
kind(myKind), fileName(myFile),
lineNumber(myNum) {}
bool operator==(const Location &rhs) {
return (this->kind == rhs.kind) &&
(this->fileName == rhs.fileName) &&
(this->lineNumber == rhs.lineNumber);
}
std::string kind;
std::string fileName;
int lineNumber;
};

// Comparator for Location sorting.
class cmpLocation {
public:
bool operator() (const Location a, const Location b) const {
if (a.kind != b.kind) {
return (a.kind < b.kind);
} else if (a.fileName != b.fileName) {
return (a.fileName < b.fileName);
} else {
return (a.lineNumber < b.lineNumber);
}
}
};
};


// This class represents an analysis this determines whether functions and
// chunks are approximate. It is consumed by our various optimizations.
class ApproxInfo : public llvm::FunctionPass {
public:
static char ID;
std::map< llvm::Function*, std::pair<std::string, int> > functionLocs;
ApproxInfo();
virtual ~ApproxInfo();
virtual const char *getPassName() const;

// Required FunctionPass interface.
virtual void findFunctionLocs(llvm::Module &mod);
virtual bool doInitialization(llvm::Module &M);
virtual bool runOnFunction(llvm::Function &F);
virtual bool doFinalization(llvm::Module &M);

std::map<llvm::Function*, bool> functionPurity;

std::set<llvm::Instruction*> preciseEscapeCheck(
std::set<llvm::Instruction*> insts,
std::set<llvm::Instruction*> *blessed=NULL);
std::set<llvm::Instruction*> preciseEscapeCheck(
std::set<llvm::BasicBlock*> blocks);
bool isPrecisePure(llvm::Function *func);
bool pointerCaptured(const llvm::Value *ptr,
const std::set<llvm::Instruction*> &region,
bool approx);

std::map< std::string, std::map<int, LineMarker> > lineMarkers;
LineMarker markerAtLine(std::string filename, int line);
LineMarker instMarker(llvm::Instruction *inst);

bool isWhitelistedPure(llvm::StringRef s);
std::set<llvm::BasicBlock*> successorsOf(llvm::BasicBlock *block);
std::set<llvm::BasicBlock*> imSuccessorsOf(llvm::BasicBlock *block);
bool storeEscapes(llvm::StoreInst *store,
const std::set<llvm::Instruction*> &insts,
bool approx=true);

// Logging.
LogDescription *logAdd(llvm::StringRef kind, llvm::StringRef filename,
const int lineno);
LogDescription *logAdd(llvm::StringRef kind, llvm::Instruction *where);

private:
void successorsOfHelper(llvm::BasicBlock *block,
std::set<llvm::BasicBlock*> &succ);
int preciseEscapeCheckHelper(std::map<llvm::Instruction*, bool> &flags,
const std::set<llvm::Instruction*> &insts);
bool approxOrLocal(std::set<llvm::Instruction*> &insts,
llvm::Instruction *inst);

// Logging.
std::map<LogDescription::Location, std::vector<LogDescription*>, LogDescription::cmpLocation> logDescs;
bool logEnabled;
llvm::raw_fd_ostream *logFile;
void dumpLog();
};

// The pass that actually performs optimizations.
struct ACCEPTPass : public llvm::FunctionPass {
static char ID;

llvm::Module *module;
std::map<std::string, int> relaxConfig; // ident -> param
std::map<std::string, int> doIt;
int opportunityId;
std::map<llvm::Function*, llvm::DISubprogram> funcDebugInfo;
ApproxInfo *AI;
bool relax;

ACCEPTPass();
virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const;
virtual const char *getPassName() const;
virtual bool runOnFunction(llvm::Function &F);
virtual bool doInitialization(llvm::Module &M);
virtual bool doFinalization(llvm::Module &M);

bool shouldSkipFunc(llvm::Function &F);
std::string siteName(std::string kind, llvm::Instruction *at);

void collectFuncDebug(llvm::Module &M);
void collectSubprogram(llvm::DISubprogram sp);
void collectType(llvm::DIType ty);

void dumpRelaxConfig();
void loadRelaxConfig();

bool optimizeSync(llvm::Function &F);
bool optimizeAcquire(llvm::Instruction *inst);
bool optimizeBarrier(llvm::Instruction *bar1);
llvm::Instruction *findCritSec(llvm::Instruction *acq,
std::set<llvm::Instruction*> &cs, LogDescription *desc);
llvm::Instruction *findApproxCritSec(llvm::Instruction *acq,
LogDescription *desc);
bool nullifyApprox(llvm::Function &F);
};

// This class searches loops and stores info on viable ones to apply automatic
// paralellization
class LoopParallelize : public llvm::LoopPass {
public:
LoopParallelize();
private:
static char ID;
ACCEPTPass *transformPass;
ApproxInfo *AI;
llvm::Module *module;

// Loop-specific info. Replaced in each runOnLoop() call
llvm::Loop *L;
llvm::Value *lower, *upper, *increment;
llvm::Value *counterPtr;
bool willInvert, isForLike, isUnsigned;
llvm::SmallVector<llvm::Instruction *, 3> incrementInstructions;
std::vector<llvm::BasicBlock *> bodyBlocks;
std::set<llvm::Value *> bodyPointers;

void recurseRemovefromLPM(llvm::Loop *L, llvm::LPPassManager &LPM);
void deleteLoop(llvm::LPPassManager &LPM);

bool isOnLoop(llvm::Instruction *inst);
bool isOnLoop(llvm::BasicBlock *bb);
bool isOnLoopBody(llvm::Instruction *inst);
bool getLowerAndUpperBounds();
llvm::Value *getPointerValue(llvm::Value *possibleLoad);
bool getIncrement();

void searchBodyPointers(llvm::BasicBlock *bodyBlock);

llvm::Function *createFunction(llvm::Function *ompFunc,
const std::set<llvm::Value *> &allocaToArgs,
llvm::ValueToValueMapTy &valueM);
llvm::Value *ensureLoad(llvm::Value *pointer, llvm::IRBuilder<> &builder);

llvm::Value *replaceCounter(llvm::Value *plower, llvm::Value *upperv,
llvm::Value *incr, llvm::IRBuilder<> &builder);

bool paralellizeLoop(llvm::LPPassManager &LPM, int logthreads);

virtual bool doInitialization(llvm::Loop *, llvm::LPPassManager &);
virtual bool doFinalization();
virtual bool runOnLoop(llvm::Loop *L, llvm::LPPassManager &LPM);
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const;
const char *getPassName() const;
};

// Information about individual instructions is always available.
bool isApprox(const llvm::Instruction *instr);
bool isApproxPtr(const llvm::Value *value);
bool isCallOf(llvm::Instruction *inst, const char *fname);
bool isAcquire(llvm::Instruction *inst);
bool isRelease(llvm::Instruction *inst);
Loading