Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
TAS-OPT
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Guruprasad Hegde
TAS-OPT
Commits
7e917d88
Commit
7e917d88
authored
Oct 23, 2019
by
guruhegde
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement doLoopSplit()
* not tested yet.
parent
1bc08f1a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
85 additions
and
25 deletions
+85
-25
src/BatchMaker.cpp
src/BatchMaker.cpp
+2
-0
src/ForLoop.cpp
src/ForLoop.cpp
+8
-10
src/LoopSplitter.cpp
src/LoopSplitter.cpp
+73
-13
src/LoopSplitter.h
src/LoopSplitter.h
+2
-2
No files found.
src/BatchMaker.cpp
View file @
7e917d88
...
...
@@ -27,6 +27,8 @@ using namespace llvm;
namespace
tas
{
// TODO Use return val array
/// Old Function Prototype:
/// Ret Fn(Type1 A, Type2 B BATCH_ARG, Type3 C BATCH_ARG);
/// BatchForm Fn Prototype:
...
...
src/ForLoop.cpp
View file @
7e917d88
...
...
@@ -9,24 +9,21 @@ using namespace llvm;
namespace
tas
{
TASForLoop
::
TASForLoop
(
LLVMContext
&
Ctx
,
BasicBlock
*
Prev
,
BasicBlock
*
Next
,
const
std
::
string
&
Name
,
Function
*
F
,
llvm
::
Value
*
TC
,
AllocaInst
*
IP
)
BasicBlock
*
Next
,
const
std
::
string
&
Name
,
Function
*
F
,
llvm
::
Value
*
TC
,
AllocaInst
*
IP
)
:
F
(
F
),
Name
(
std
::
move
(
Name
)),
TripCount
(
TC
),
IdxVarPtr
(
IP
)
{
addEmptyLoop
(
Ctx
,
Prev
,
Next
);
}
void
TASForLoop
::
addEmptyLoop
(
LLVMContext
&
Ctx
,
BasicBlock
*
Prev
,
BasicBlock
*
Next
)
{
void
TASForLoop
::
addEmptyLoop
(
LLVMContext
&
Ctx
,
BasicBlock
*
Prev
,
BasicBlock
*
Next
)
{
PreHeader
=
BasicBlock
::
Create
(
Ctx
,
Name
+
".preheader"
,
F
,
Next
);
Header
=
BasicBlock
::
Create
(
Ctx
,
Name
+
".header"
,
F
,
Next
);
Latch
=
BasicBlock
::
Create
(
Ctx
,
Name
+
".latch"
,
F
,
Next
);
// Update phi node edge if any
IRBuilder
<>
Builder
(
Next
);
auto
*
PN
=
&*
(
Next
->
phis
().
begin
());
if
(
PN
)
PN
->
addIncoming
(
Builder
.
getInt32
(
0
),
Header
);
Builder
.
SetInsertPoint
(
PreHeader
);
IRBuilder
<>
Builder
(
PreHeader
);
Builder
.
CreateStore
(
Builder
.
getInt32
(
0
),
IdxVarPtr
);
Builder
.
CreateBr
(
Header
);
...
...
@@ -38,7 +35,7 @@ void TASForLoop::addEmptyLoop(LLVMContext & Ctx, BasicBlock * Prev, BasicBlock *
Builder
.
SetInsertPoint
(
Header
);
IndexVar
=
Builder
.
CreateLoad
(
IdxVarPtr
);
auto
*
icmp
=
Builder
.
CreateICmpSLT
(
IndexVar
,
TripCount
,
"loop-predicate"
);
// Stitch entry point in control flow.
if
(
Prev
)
{
if
(
Prev
->
getTerminator
()
->
getNumOperands
()
==
3
)
...
...
@@ -57,7 +54,8 @@ void TASForLoop::setLoopBody(BasicBlock * BodyBB) {
BodyBB
->
getTerminator
()
->
setSuccessor
(
0
,
Latch
);
}
void
TASForLoop
::
setLoopBody
(
BasicBlock
*
EntryBB
,
BasicBlock
*
ExitingBB
)
{
void
TASForLoop
::
setLoopBody
(
BasicBlock
*
EntryBB
,
BasicBlock
*
ExitingBB
)
{
EntryBody
=
EntryBB
;
ExitingBody
=
ExitingBB
;
Header
->
getTerminator
()
->
setSuccessor
(
0
,
EntryBody
);
...
...
src/LoopSplitter.cpp
View file @
7e917d88
...
...
@@ -17,7 +17,7 @@ using namespace llvm;
namespace
tas
{
void
LoopSplitter
::
addAdapterBasicBlocks
(
Instruction
*
SP
)
{
void
LoopSplitter
::
addAdapterBasicBlocks
(
Instruction
*
SP
,
Value
*
Idx
)
{
auto
TopHalf
=
SP
->
getParent
();
auto
BottomHalf
=
TopHalf
->
splitBasicBlock
(
SP
->
getNextNode
());
...
...
@@ -26,18 +26,22 @@ void LoopSplitter::addAdapterBasicBlocks(Instruction * SP) {
BranchInst
::
Create
(
DistBB
,
CollectBB
);
setSuccessor
(
TopHalf
,
CollectBB
);
setSuccessor
(
CollectBB
,
DistBB
);
LoopSplitEdgeBlocks
.
push_back
(
CollectBB
);
// General case: Find all edges from basic blocks above tophalf
and connect it to
// CollectBB, use switch Inst
// General case: Find all edges from basic blocks above tophalf
//
and connect it to
CollectBB, use switch Inst
IRBuilder
<>
Builder
(
&
F
->
getEntryBlock
().
front
());
auto
BrTargetAlloca
=
Builder
.
CreateAlloca
(
Builder
.
getInt32Ty
());
auto
BrTgtArray
=
createArray
(
F
,
Builder
.
getInt32Ty
(),
32
/*XXX Max Batch size*/
);
//auto BrTargetAlloca = Builder.CreateAlloca(Builder.getInt32Ty());
Builder
.
SetInsertPoint
(
DistBB
);
auto
BrVal
=
Builder
.
CreateLoad
(
BrTargetAlloca
);
auto
BrValPtr
=
Builder
.
CreateGEP
(
BrTgtArray
,
{
Builder
.
getInt64
(
0
),
Idx
});
auto
BrVal
=
Builder
.
CreateLoad
(
BrValPtr
);
auto
SwitchI
=
Builder
.
CreateSwitch
(
BrVal
,
BottomHalf
);
// XXX We assume now CFG we have is the one after block predication transformation.
// XXX We assume now CFG we have is the one after block
// predication transformation.
SmallVector
<
BasicBlock
*
,
4
>
DivergeBlocks
;
SmallVector
<
std
::
pair
<
Value
*
,
BasicBlock
*>
,
4
>
TargetBlocks
;
DivergeBlocks
.
push_back
(
TopHalf
->
getUniquePredecessor
());
...
...
@@ -50,13 +54,14 @@ void LoopSplitter::addAdapterBasicBlocks(Instruction * SP) {
auto
TgtBB
=
TermI
->
getSuccessor
(
1
);
auto
TgtBBVal
=
BBToId
[
TgtBB
];
Builder
.
CreateStore
(
TgtBBVal
,
BrTargetAlloca
);
auto
BrValPtr
=
Builder
.
CreateGEP
(
BrTgtArray
,
{
Builder
.
getInt64
(
0
),
Idx
});
Builder
.
CreateStore
(
TgtBBVal
,
BrValPtr
);
TermI
->
setSuccessor
(
1
,
CollectBB
);
SwitchI
->
addCase
(
TgtBBVal
,
TgtBB
);
}
}
bool
LoopSplitter
::
prepareForLoopSplit
(
Function
*
F
,
Stats
&
stat
)
{
bool
LoopSplitter
::
prepareForLoopSplit
(
Function
*
F
,
Stats
&
stat
,
Value
*
Idx
)
{
auto
AnnotatedVars
=
detectExpPtrVars
(
F
);
auto
VarUsePoints
=
detectExpPtrUses
(
AnnotatedVars
);
...
...
@@ -64,10 +69,12 @@ bool LoopSplitter::prepareForLoopSplit(Function *F, Stats & stat) {
unsigned
i
=
0
;
IRBuilder
<>
Builder
(
F
->
getContext
());
for_each
(
*
F
,
[
&
]
(
const
auto
&
BB
)
{
BBToId
.
insert
(
std
::
make_pair
(
&
BB
,
Builder
.
getInt32
(
++
i
)));
});
[
&
]
(
const
auto
&
BB
)
{
BBToId
.
insert
(
std
::
make_pair
(
&
BB
,
Builder
.
getInt32
(
++
i
)));
});
for_each
(
VarUsePoints
,
[
&
]
(
auto
&
VarUse
)
{
addAdapterBasicBlocks
(
VarUse
);
});
[
&
]
(
auto
&
VarUse
)
{
addAdapterBasicBlocks
(
VarUse
,
Idx
);
});
for_each
(
VarUsePoints
,
[
&
]
(
auto
&
VarUse
)
{
insertLLVMPrefetchIntrinsic
(
F
,
VarUse
);
});
...
...
@@ -77,17 +84,70 @@ bool LoopSplitter::prepareForLoopSplit(Function *F, Stats & stat) {
return
VarUsePoints
.
size
()
!=
0
;
}
Value
*
getLoopTripCount
(
Loop
*
L0
)
{
auto
Header
=
L0
->
getHeader
();
auto
Cond
=
cast
<
BranchInst
>
(
Header
->
getTerminator
())
->
getCondition
();
return
cast
<
LoadInst
>
(
cast
<
ICmpInst
>
(
Cond
)
->
getOperand
(
1
))
->
getOperand
(
0
);
}
void
doLoopSplit
(
Function
*
F
,
Loop
*
L0
,
BasicBlock
*
SplitBlock
)
{
auto
OldHeader
=
L0
->
getHeader
();
auto
ExitBlock
=
OldHeader
->
getTerminator
()
->
getSuccessor
(
1
);
auto
DistBB
=
SplitBlock
->
getUniqueSuccessor
();
BasicBlock
*
EntryBlock
=
nullptr
;
for
(
auto
BB
:
predecessors
(
OldHeader
))
{
if
(
BB
!=
L0
->
getLoopLatch
())
EntryBlock
=
BB
;
}
auto
NewPreHeader
=
BasicBlock
::
Create
(
F
->
getContext
(),
"preheader"
,
F
);
auto
NewHeader
=
BasicBlock
::
Create
(
F
->
getContext
(),
"header"
,
F
);
auto
NewLatch
=
BasicBlock
::
Create
(
F
->
getContext
(),
"latch"
,
F
);
auto
IndexVar
=
getLoopIndexVar
(
L0
);
auto
TripCount
=
cast
<
AllocaInst
>
(
getLoopTripCount
(
L0
));
errs
()
<<
*
IndexVar
<<
" "
<<
*
TripCount
<<
"
\n
"
;
IRBuilder
<>
Builder
(
NewPreHeader
);
Builder
.
CreateStore
(
Builder
.
getInt32
(
0
),
IndexVar
);
Builder
.
CreateBr
(
NewHeader
);
Builder
.
SetInsertPoint
(
NewLatch
);
auto
BI
=
Builder
.
CreateBr
(
NewHeader
);
addIncrementIndexOp
(
IndexVar
,
BI
);
Builder
.
SetInsertPoint
(
NewHeader
);
auto
IndexVarVal
=
Builder
.
CreateLoad
(
IndexVar
);
auto
TripCountVal
=
Builder
.
CreateLoad
(
TripCount
);
auto
*
icmp
=
Builder
.
CreateICmpSLT
(
IndexVarVal
,
TripCountVal
,
"loop-predicate"
);
auto
NewEntryBB
=
cast
<
BranchInst
>
(
OldHeader
->
getTerminator
())
->
getSuccessor
(
0
);
Builder
.
CreateCondBr
(
icmp
,
NewEntryBB
,
L0
->
getHeader
());
SplitBlock
->
getTerminator
()
->
setSuccessor
(
0
,
NewLatch
);
OldHeader
->
getTerminator
()
->
setSuccessor
(
0
,
DistBB
);
OldHeader
->
getTerminator
()
->
setSuccessor
(
1
,
ExitBlock
);
setSuccessor
(
EntryBlock
,
NewPreHeader
);
}
bool
LoopSplitter
::
run
()
{
bool
changed
=
prepareForLoopSplit
(
F
,
stat
);
if
(
!
changed
)
return
false
;
// If no loops, we are done.
if
(
LI
->
begin
()
==
LI
->
end
())
return
false
;
// XXX Assume only one loop for now.
auto
L0
=
*
LI
->
begin
();
auto
IndexVar
=
getLoopIndexVar
(
L0
);
bool
changed
=
prepareForLoopSplit
(
F
,
stat
,
IndexVar
);
if
(
!
changed
)
return
false
;
auto
&
SplitBB
=
LoopSplitEdgeBlocks
.
front
();
doLoopSplit
(
F
,
L0
,
SplitBB
);
//assert (L0->getLoopPreheader() && "Loop doesn't have preheader!"
);
F
->
print
(
errs
()
);
return
true
;
}
...
...
src/LoopSplitter.h
View file @
7e917d88
...
...
@@ -37,14 +37,14 @@ class LoopSplitter {
llvm
::
DenseMap
<
const
llvm
::
BasicBlock
*
,
llvm
::
ConstantInt
*>
BBToId
;
llvm
::
SmallVector
<
llvm
::
BasicBlock
*
,
4
>
LoopSplitEdgeBlocks
;
bool
prepareForLoopSplit
(
llvm
::
Function
*
F
,
Stats
&
stat
);
bool
prepareForLoopSplit
(
llvm
::
Function
*
F
,
Stats
&
stat
,
llvm
::
Value
*
Idx
);
public:
LoopSplitter
(
llvm
::
Function
*
F_
,
llvm
::
LoopInfo
*
LI_
)
:
F
(
F_
),
LI
(
LI_
)
{}
bool
run
();
Stats
&
getStats
()
{
return
stat
;
}
void
addAdapterBasicBlocks
(
llvm
::
Instruction
*
SP
);
void
addAdapterBasicBlocks
(
llvm
::
Instruction
*
SP
,
llvm
::
Value
*
Idx
);
};
}
// tas namespace
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment