Skip to content
Snippets Groups Projects
Commit 92143238 authored by kotsifa2's avatar kotsifa2
Browse files

Deleted DFG2LLVM pass.

parent f25cb438
No related branches found
No related tags found
No related merge requests found
add_llvm_loadable_module( LLVMBuildDFG
DFG2LLVM.cpp
)
//=== DFG2LLVM.cpp ===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "DFG2LLVM"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/BuildDFG/BuildDFG.h"
using namespace llvm;
using namespace builddfg;
//STATISTIC(IntrinsicCounter, "Counts number of visc intrinsics greeted");
namespace {
// DFG2LLVM - The first implementation.
struct DFG2LLVM : public ModulePass {
static char ID; // Pass identification, replacement for typeid
DFG2LLVM() : ModulePass(ID) {}
private:
// Member variables
// Functions
public:
bool runOnModule(Module &M);
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<BuildDFG>();
}
};
// Visitor for Code generation traversal (tree traversal for now)
class CodeGenTraversal : public DFNodeVisitor {
private:
//Member variables
Module &M;
BuildDFG &DFG;
//Functions
void codeGen(DFInternalNode* N) {
}
// Code generation for leaf nodes
void codeGen(DFLeafNode* N) {
std::vector<IntrinsicInst *> IItoRemove;
BuildDFG::HandleToDFNode Leaf_HandleToDFNodeMap;
// Get the function associated woth the dataflow node
Function *F = N->getFuncPointer();
// Go through all the instructions
for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
Instruction *I = &(*i);
// Leaf nodes should not contain VISC graph intrinsics or launch
assert(!BuildDFG::isViscLaunchIntrinsic(I) && "Launch intrinsic within a dataflow graph!");
assert(!BuildDFG::isViscGraphIntrinsic(I) && "VISC graph intrinsic within a leaf dataflow node!");
if (BuildDFG::isViscQueryIntrinsic(I)) {
IntrinsicInst* II = dyn_cast<IntrinsicInst>(I);
IntrinsicInst* ArgII;
DFNode* ArgDFNode;
/******************************************************************************
* Handle VISC Query intrinsics *
******************************************************************************/
switch (II->getIntrinsicID()) {
/**************************** llvm.visc.getNode() *****************************/
case Intrinsic::visc_getNode: {
// add mapping <intrinsic, this node> to the node-specific map
Leaf_HandleToDFNodeMap[II] = N;
IItoRemove.push_back(II);
}
break;
/************************* llvm.visc.getParentNode() **************************/
case Intrinsic::visc_getParentNode: {
// get the parent node of the arg node
// get argument node
ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
ArgDFNode = Leaf_HandleToDFNodeMap[ArgII];
// get the parent node of the arg node
// Add mapping <intrinsic, parent node> to the node-specific map
// the argument node must have been added to the map, orelse the
// code could not refer to it
Leaf_HandleToDFNodeMap[II] = ArgDFNode->getParent();
IItoRemove.push_back(II);
}
break;
/*************************** llvm.visc.getNumDims() ***************************/
case Intrinsic::visc_getNumDims: {
// get node from map
// get the appropriate field
int numOfDim = Leaf_HandleToDFNodeMap[ArgII]->getNumOfDim();
IntegerType* IntTy = Type::getInt32Ty(getGlobalContext());
ConstantInt* numOfDimConstant = ConstantInt::getSigned(IntTy, (int64_t) numOfDim);
// Replace the result of the intrinsic with the computed value
II->replaceAllUsesWith(numOfDimConstant);
IItoRemove.push_back(II);
}
break;
/*********************** llvm.visc.getNodeInstanceID() ************************/
case Intrinsic::visc_getNodeInstanceID: {
ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
ArgDFNode = Leaf_HandleToDFNodeMap[ArgII];
// A leaf node always has a parent
DFNode* ParentDFNode = DFG.getHandleToDFNodeMap()[ArgII];
// Get specified dimension
// (dim = 0) => x
// (dim = 1) => y
// (dim = 2) => z
ConstantInt * DimConstant = cast<ConstantInt>(II->getOperand(1));
int dim = (int) DimConstant->getSExtValue();
assert((dim >= 0) && (dim < 3) && "Invalid dimension argument");
// Argument of the function to be called
ArrayRef<Value *> Args(DimConstant);
// The following is to find which function to call
Function * OpenCLFunction;
int parentLevel = ParentDFNode->getLevel();
if (!parentLevel) {
// We only have one level in the hierarchy, but still need to
// specify a global id
assert((dim != 2) && "Invalid dimension argument");
FunctionType* FT =
FunctionType::get(Type::getInt32Ty(getGlobalContext()),
std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
false);
OpenCLFunction = cast<Function>
(M.getOrInsertFunction(StringRef("get_global_id"), FT));
} else if (Leaf_HandleToDFNodeMap[ArgII] == Leaf_HandleToDFNodeMap[II]) {
// We are asking for this node's id with respect to its parent
// this is a local id call
FunctionType* FT =
FunctionType::get(Type::getInt32Ty(getGlobalContext()),
std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
false);
OpenCLFunction = cast<Function>
(M.getOrInsertFunction(StringRef("get_local_id"), FT));
} else if (Leaf_HandleToDFNodeMap[ArgII] == N->getParent()) {
// We are asking for this node's parent's id with respect to its
// parent: this is a group id call
FunctionType* FT =
FunctionType::get(Type::getInt32Ty(getGlobalContext()),
std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
false);
OpenCLFunction = cast<Function>
(M.getOrInsertFunction(StringRef("get_group_id"), FT));
} else {
assert(false && "Unable to translate this intrinsic");
}
// Create call instruction, insert it before the intrinsic and
// replace the uses of the previous instruction with the new one
CallInst* CI = CallInst::Create(OpenCLFunction, Args, "", II);
II->replaceAllUsesWith(CI);
IItoRemove.push_back(II);
}
break;
/********************** llvm.visc.getNumNodeInstances() ***********************/
case Intrinsic::visc_getNumNodeInstances: {
//TODO: think about whether this is the best way to go
// there are hw specific registers. therefore it is good to have the intrinsic
// but then, why do we need to keep that info in the graph?
// (only for the kernel configuration during the call)
ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
ArgDFNode = Leaf_HandleToDFNodeMap[ArgII];
// A leaf node always has a parent
DFNode* ParentDFNode = DFG.getHandleToDFNodeMap()[ArgII];
// Get specified dimension
ConstantInt * DimConstant = cast<ConstantInt>(II->getOperand(1));
int dim = (int) DimConstant->getSExtValue();
assert((dim >= 0) && (dim < 3) && "Invalid dimension argument");
// Argument of the function to be called
ArrayRef<Value *> Args(DimConstant);
// The following is to find which function to call
Function * OpenCLFunction;
int parentLevel = ParentDFNode->getLevel();
if (!parentLevel) {
// We only have one level in the hierarchy, thus the node
// instances are global_size (gridDim x blockDim)
FunctionType* FT =
FunctionType::get(Type::getInt32Ty(getGlobalContext()),
std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
false);
OpenCLFunction = cast<Function>
(M.getOrInsertFunction(StringRef("get_global_size"), FT));
} else if (Leaf_HandleToDFNodeMap[ArgII] == Leaf_HandleToDFNodeMap[II]) {
// We are asking for this node's instances
// this is a local size (block dim) call
FunctionType* FT =
FunctionType::get(Type::getInt32Ty(getGlobalContext()),
std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
false);
OpenCLFunction = cast<Function>
(M.getOrInsertFunction(StringRef("get_local_size"), FT));
} else if (Leaf_HandleToDFNodeMap[ArgII] == N->getParent()) {
// We are asking for this node's parent's instances
// this is a (global_size/local_size) (grid dim) call
FunctionType* FT =
FunctionType::get(Type::getInt32Ty(getGlobalContext()),
std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
false);
OpenCLFunction = cast<Function>
(M.getOrInsertFunction(StringRef("get_num_groups"), FT));
} else {
assert(false && "Unable to translate this intrinsic");
}
// Create call instruction, insert it before the intrinsic and
// replace the uses of the previous instruction with the new one
CallInst* CI = CallInst::Create(OpenCLFunction, Args, "", II);
II->replaceAllUsesWith(CI);
IItoRemove.push_back(II);
}
break;
default:
assert(false && "Unknown VISC Intrinsic!");
break;
}
} else {
//TODO: how to handle address space qualifiers in load/store
}
}
//TODO:
// When to replace the uses?
// In which order is it safe to replace the instructions in
// IItoReplace?
// Probably in the reverse order in the vectors
// It is a good idea to have them in one vector and chech the type
// using dyn_cast in order to determine if we replace with inst or value
//We need to do this explicitly: DCE pass will not remove them because we
// have assumed theworst memory behaviour for these function calls
for (std::vector<IntrinsicInst *>::iterator i = IItoRemove.begin();
i != IItoRemove.end(); ++i)
(*i)->eraseFromParent();
}
public:
// Constructor
CodeGenTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) { }
virtual void visit(DFInternalNode* N) {
errs() << "Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n";
codeGen(N);
errs() << "DONE" << "\n";
for(DFGraph::children_iterator i = N->getChildGraph()->begin(),
e = N->getChildGraph()->end(); i != e; ++i) {
DFNode* child = *i;
child->applyDFNodeVisitor(*this);
}
}
virtual void visit(DFLeafNode* N) {
errs() << "Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n";
codeGen(N);
errs() << "DONE" << "\n";
}
};
bool DFG2LLVM::runOnModule(Module &M) {
// Get the BuildDFG Analysis Results:
// - Dataflow graph
// - Maps from i8* hansles to DFNode and DFEdge
BuildDFG &DFG = getAnalysis<BuildDFG>();
DFInternalNode *Root = DFG.getRoot();
// BuildDFG::HandleToDFNode &HandleToDFNodeMap = DFG.getHandleToDFNodeMap();
// BuildDFG::HandleToDFEdge &HandleToDFEdgeMap = DFG.getHandleToDFEdgeMap();
// Visitor for Code Generation Graph Traversal
CodeGenTraversal *CGTVisitor = new CodeGenTraversal(M, DFG);
// Initiate code generation for root DFNode
CGTVisitor->visit(Root);
//TODO: Edit module epilogue to remove the VISC intrinsic declarations
return true;
}
} // End of namespace
char DFG2LLVM::ID = 0;
static RegisterPass<DFG2LLVM> X("DFG2LLVM",
"Dataflow Graph to LLVM for nvptx Pass",
false /* does not modify the CFG */,
true /* transformation, not just analysis */);
##===- lib/Transforms/BuildDFG/Makefile -----------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../
LIBRARYNAME = LLVMDFG2LLVM
LOADABLE_MODULE = 1
SHARED_LIBRARY = 1
#BUILD_ARCHIVE = 1
#USEDLIBS =
include $(LEVEL)/Makefile.common
......@@ -9,7 +9,7 @@
LEVEL = ../..
PARALLEL_DIRS = Utils Instrumentation Scalar InstCombine IPO Vectorize Hello \
ObjCARC BuildDFG DFG2LLVM
ObjCARC BuildDFG
include $(LEVEL)/Makefile.config
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment