Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
hpvm-release
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
llvm
hpvm-release
Commits
cd55e712
Commit
cd55e712
authored
10 years ago
by
kotsifa2
Browse files
Options
Downloads
Patches
Plain Diff
Transformation of non-void functions to void in dfg2llvm_nvptx pass.
(more testing required).
parent
e9d3cf98
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
+141
-18
141 additions, 18 deletions
llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
with
141 additions
and
18 deletions
llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
+
141
−
18
View file @
cd55e712
...
...
@@ -17,6 +17,8 @@
#include
"llvm/Transforms/Utils/Cloning.h"
#include
"llvm/BuildDFG/BuildDFG.h"
#include
<sstream>
using
namespace
llvm
;
using
namespace
builddfg
;
...
...
@@ -58,6 +60,10 @@ namespace {
ValueMap
<
Function
*
,
Function
*>
FMap
;
//Functions
void
addReturnValueArgs
(
Function
*
F
);
Argument
*
getArgumentFromEnd
(
Function
*
F
,
unsigned
offset
);
Argument
*
getArgumentAt
(
Function
*
F
,
unsigned
offset
);
void
codeGen
(
DFInternalNode
*
N
);
void
codeGen
(
DFLeafNode
*
N
);
...
...
@@ -104,27 +110,29 @@ namespace {
// Get the function associated with the dataflow node
Function
*
F
=
N
->
getFuncPointer
();
// Look up if we have visited this function before. If we have, then just
// get the cloned function pointer from FMap. Otherwise, create the cloned
// function and add it to the FMap.
Function
*
F_nvptx
;
if
(
FMap
.
count
(
F
))
{
F_nvptx
=
FMap
[
F
];
}
else
{
// Clone the function
ValueToValueMapTy
VMap
;
F_nvptx
=
CloneFunction
(
F
,
VMap
,
true
);
// Look up if we have visited this function before. If we have, then just
// get the cloned function pointer from FMap. Otherwise, create the cloned
// function and add it to the FMap.
Function
*
F_nvptx
;
if
(
FMap
.
count
(
F
))
{
F_nvptx
=
FMap
[
F
];
}
else
{
// Clone the function
ValueToValueMapTy
VMap
;
F_nvptx
=
CloneFunction
(
F
,
VMap
,
true
);
// Insert the cloned function into the module
M
.
getFunctionList
().
push_back
(
F_nvptx
);
// Insert the cloned function into the module
M
.
getFunctionList
().
push_back
(
F_nvptx
);
DEBUG
(
errs
()
<<
*
F_nvptx
->
getType
());
DEBUG
(
errs
()
<<
*
F_nvptx
);
DEBUG
(
errs
()
<<
*
F_nvptx
->
getType
());
DEBUG
(
errs
()
<<
*
F_nvptx
);
//Add old func: new func pair to the FMap
FMap
[
F
]
=
F_nvptx
;
}
//Add old func: new func pair to the FMap
FMap
[
F
]
=
F_nvptx
;
}
addReturnValueArgs
(
F_nvptx
);
// Go through all the instructions
for
(
inst_iterator
i
=
inst_begin
(
F_nvptx
),
e
=
inst_end
(
F_nvptx
);
i
!=
e
;
++
i
)
{
...
...
@@ -373,6 +381,121 @@ namespace {
return
true
;
}
std
::
string
convertInt
(
int
number
)
{
std
::
stringstream
ss
;
//create a stringstream
ss
<<
number
;
//add number to the stream
return
ss
.
str
();
//return a string with the contents of the stream
}
void
findReturnInst
(
Function
*
F
,
std
::
vector
<
ReturnInst
*>
&
ReturnInstVec
)
{
for
(
inst_iterator
i
=
inst_begin
(
F
),
e
=
inst_end
(
F
);
i
!=
e
;
++
i
)
{
Instruction
*
I
=
&
(
*
i
);
ReturnInst
*
RI
=
dyn_cast
<
ReturnInst
>
(
I
);
if
(
RI
)
{
ReturnInstVec
.
push_back
(
RI
);
}
}
}
void
CodeGenTraversal
::
addReturnValueArgs
(
Function
*
F
)
{
// FIXME: Maybe do that using the Node?
StructType
*
FRetTy
=
cast
<
StructType
>
(
F
->
getReturnType
());
assert
(
FRetTy
&&
"Return Type is NULL, it should be a struct"
);
// Keeps return statements, because we will need to replace them
std
::
vector
<
ReturnInst
*>
RItoRemove
;
findReturnInst
(
F
,
RItoRemove
);
// Check for { } return struct, which means that the function returns void
if
(
FRetTy
->
getNumElements
()
==
0
)
{
DEBUG
(
errs
()
<<
"
\t
Function output struct is void
\n
"
);
DEBUG
(
errs
()
<<
"
\t
No parameters added
\n
"
);
// Replacing return statements with others returning void
for
(
std
::
vector
<
ReturnInst
*>::
iterator
i
=
RItoRemove
.
begin
(),
e
=
RItoRemove
.
end
();
i
!=
e
;
++
i
)
{
ReturnInst
::
Create
((
F
->
getContext
()),
0
,
(
*
i
));
(
*
i
)
->
eraseFromParent
();
}
DEBUG
(
errs
()
<<
"
\t
Changed return statements to return void
\n
"
);
return
;
}
// The struct has return values that need to be converted to parameters
int
initialNumParams
=
F
->
arg_size
();
// Create the extra parameters with appropriate pointer types
for
(
unsigned
i
=
0
;
i
<
FRetTy
->
getNumElements
();
i
++
)
{
Type
*
FieldType
=
FRetTy
->
getElementType
(
i
);
Type
*
ArgType
=
FieldType
->
getPointerTo
();
//TODO: AddressSpace
new
Argument
(
ArgType
,
"ret_arg_"
+
convertInt
(
i
),
F
);
}
DEBUG
(
errs
()
<<
"
\t
Created parameters
\n
"
);
// Create the argument type list with added argument types
std
::
vector
<
Type
*>
ArgTypes
;
for
(
Function
::
const_arg_iterator
ai
=
F
->
arg_begin
(),
ae
=
F
->
arg_end
();
ai
!=
ae
;
++
ai
)
{
ArgTypes
.
push_back
(
ai
->
getType
());
}
// Find where the new parameters start in the header
Function
::
arg_iterator
ai
,
ae
;
int
check
=
0
;
for
(
ai
=
F
->
arg_begin
(),
ae
=
F
->
arg_end
();
ai
!=
ae
;
++
ai
)
{
if
(
ai
->
getName
().
startswith
(
"ret_arg_"
))
break
;
check
++
;
}
DEBUG
(
errs
()
<<
"
\t
check = "
<<
check
<<
"
\t
initialNumParams = "
<<
initialNumParams
<<
"
\n
"
);
assert
(
check
==
initialNumParams
);
DEBUG
(
errs
()
<<
"
\t
Replacing Return statements
\n
"
);
// Replace return statements with extractValue and store instructions
for
(
std
::
vector
<
ReturnInst
*>::
iterator
rii
=
RItoRemove
.
begin
(),
rie
=
RItoRemove
.
end
();
rii
!=
rie
;
++
rii
)
{
ReturnInst
*
RI
=
(
*
rii
);
Value
*
RetVal
=
RI
->
getReturnValue
();
// assert(RetVal && "Return value should not be null at this point");
// StructType* RetType = cast<StructType>(RetVal->getType());
// assert(RetType && "Return type is not a struct");
Function
::
arg_iterator
ret_ai
=
ai
;
for
(
unsigned
i
=
0
;
i
<
FRetTy
->
getNumElements
();
i
++
,
++
ret_ai
)
{
std
::
vector
<
unsigned
>
IndexList
;
IndexList
.
push_back
(
i
);
ExtractValueInst
*
EI
=
ExtractValueInst
::
Create
(
RetVal
,
IndexList
,
Twine
(
""
),
RI
);
// StoreInst* SI = new StoreInst(EI, &(*ret_ai), RI);
new
StoreInst
(
EI
,
&
(
*
ret_ai
),
RI
);
}
ReturnInst
::
Create
((
F
->
getContext
()),
0
,
RI
);
RI
->
eraseFromParent
();
}
DEBUG
(
errs
()
<<
"
\t
Replaced return statements
\n
"
);
// Adding new arguments to the function argument list, would not change the
// function type. We need to change the type of this function to reflect the
// added arguments
Type
*
VoidRetType
=
Type
::
getVoidTy
(
F
->
getContext
());
FunctionType
*
FTy
=
FunctionType
::
get
(
VoidRetType
,
ArgTypes
,
F
->
isVarArg
());
PointerType
*
PTy
=
PointerType
::
get
(
FTy
,
cast
<
PointerType
>
(
F
->
getType
())
->
getAddressSpace
());
// Change the function type
F
->
mutateType
(
PTy
);
}
}
// End of namespace
char
DFG2LLVM_NVPTX
::
ID
=
0
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment