Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:beehive-lab/TornadoVM into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
jjfumero committed Jun 28, 2021
2 parents 3f66218 + c3cac43 commit 0463f8b
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.graalvm.compiler.core.common.cfg.Loop;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.BeginNode;
import org.graalvm.compiler.nodes.EndNode;
Expand All @@ -40,6 +43,7 @@
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
Expand All @@ -53,7 +57,7 @@ public class OCLBlockVisitor implements ControlFlowGraph.RecursiveVisitor<Block>
OCLCompilationResultBuilder openclBuilder;
OCLAssembler asm;
Set<Block> merges;
Set<Block> closedLoops;
Map<Block, Integer> closedLoops;
Set<Block> switches;
Set<Node> switchClosed;
HashMap<Block, Integer> pending;
Expand All @@ -67,7 +71,7 @@ public OCLBlockVisitor(OCLCompilationResultBuilder resBuilder) {
merges = new HashSet<>();
switches = new HashSet<>();
switchClosed = new HashSet<>();
closedLoops = new HashSet<>();
closedLoops = new HashMap<>();
pending = new HashMap<>();
rmvEndBracket = new HashSet<>();
}
Expand Down Expand Up @@ -255,54 +259,85 @@ private void closeSwitchStatement(Block block) {
}
}

private boolean wasBlockAlreadyClosed(Block b) {
Block[] successors = b.getSuccessors();
for (Block s : successors) {
if (closedLoops.contains(s)) {
return true;
}
private boolean wasBlockAlreadyClosed(Block block) {
Block dominator = block.getDominator();
if (dominator.getLoop() != null) {
int closeCount = closedLoops.getOrDefault(dominator.getLoop().getHeader(), 0);
return closeCount == dominator.getLoop().getLoopExits().size();
}
return false;
}

private void closeScope(Block block) {
private void incrementClosedLoops(Block loopBeginBlock) {
int closedLoopCount = closedLoops.getOrDefault(loopBeginBlock, 0);
closedLoops.put(loopBeginBlock, closedLoopCount + 1);
}

private void closeScope(Block block, Block loopBeginBlock) {
if (block.getBeginNode() instanceof LoopExitNode) {
if (!(block.getDominator().getDominator() != null && block.getDominator().getDominator().getBeginNode() instanceof MergeNode)) {
/*
* Only close scope if the loop-exit node does not depend on a merge node. In
* such case, the merge will generate the correct close scope.
*/
asm.endScope(block.toString());
closedLoops.add(block);
incrementClosedLoops(loopBeginBlock);
}
} else {
asm.endScope(block.toString());
closedLoops.add(block);
incrementClosedLoops(loopBeginBlock);
}
}

private boolean isBlockInABreak(Block block, Block pdom) {
return (pdom.getEndNode() instanceof ReturnNode && //
block.getBeginNode() instanceof LoopExitNode && //
block.getEndNode() instanceof EndNode && //
block.getDominator() != null && //
block.getDominator().getEndNode() instanceof IfNode && //
block.getDominator().getBeginNode() instanceof LoopBeginNode);
private boolean isComplexLoopCondition(Block block) {
Loop<Block> loop = block.getLoop();
LoopExitNode exitNode = block.getBeginNode() instanceof LoopExitNode ? (LoopExitNode) block.getBeginNode() : null;

if (loop != null || exitNode != null) {
StructuredGraph graph = block.getBeginNode().graph();

Block loopHeaderBlock = exitNode != null ? graph.getLastSchedule().getNodeToBlockMap().get(exitNode.loopBegin()) : loop.getHeader();
for (Block loopSucc : loopHeaderBlock.getSuccessors()) {
if (loopSucc.getEndNode() instanceof IfNode) {
return true;
}
}
}
return false;
}

private boolean isBlockInABreak(Block block) {
if (block.getBeginNode() instanceof LoopExitNode) {
LoopExitNode loopExitNode = (LoopExitNode) block.getBeginNode();
LoopBeginNode loopBeginNode = loopExitNode.loopBegin();
Block loopBeginBlock = loopBeginNode.graph().getLastSchedule().getNodeToBlockMap().get(loopBeginNode);
for (Block pred : block.getPredecessors()) {
if (pred == loopBeginBlock) {
return false;
}
}
return true;
}
return false;
}

@Override
public void exit(Block block, Block value) {
if (block.isLoopEnd()) {
LoopEndNode loopEndNode = (LoopEndNode) block.getEndNode();
LoopBeginNode loopBeginNode = loopEndNode.loopBegin();
Block loopBeginBlock = loopBeginNode.graph().getLastSchedule().getNodeToBlockMap().get(loopBeginNode);

// Temporary fix to remove the end scope of the most outer loop
// without changing the loop schematics in IR level.
loopEnds++;
if (openclBuilder.shouldRemoveLoop()) {
if (loopCount - loopEnds > 0) {
asm.endScope(block.toString());
closedLoops.add(block);
incrementClosedLoops(loopBeginBlock);
}
} else {
closeScope(block);
closeScope(block, loopBeginBlock);
}
}

Expand All @@ -318,7 +353,7 @@ public void exit(Block block, Block value) {
if (!(pdom.getBeginNode() instanceof MergeNode && merges.contains(block) && block.getPredecessorCount() > 2)) {
// We need to check that none of the blocks reachable from dominators has been
// already closed.
if (!wasBlockAlreadyClosed(block.getDominator()) && !isBlockInABreak(block, pdom)) {
if (!wasBlockAlreadyClosed(block) && !(!isComplexLoopCondition(block) && isBlockInABreak(block))) {
if (!(rmvEndBracket.contains(block))) {
asm.endScope(block.toString());
}
Expand All @@ -332,6 +367,12 @@ public void exit(Block block, Block value) {
} else {
closeBranchBlock(block);
}

/*
* It generates instructions that are relocated from within the for-loop to after the for-loop.
* https://github.com/beehive-lab/TornadoVM/pull/129
*/
openclBuilder.emitRelocatedInstructions(block);
}

private void closeIfBlock(Block block, Block dom) {
Expand All @@ -341,8 +382,11 @@ private void closeIfBlock(Block block, Block dom) {
// true branch, until the false branch has been closed.
boolean isLoopEnd = block.getEndNode() instanceof LoopEndNode;
boolean isTrueBranch = ifNode.trueSuccessor() == block.getBeginNode();
if (!(isTrueBranch & isLoopEnd)) {
if (!(isTrueBranch && isLoopEnd)) {
asm.endScope(block.toString());
if (block.getLoop() != null) {
incrementClosedLoops(block.getLoop().getHeader());
}
}
}
}
Expand Down Expand Up @@ -382,8 +426,21 @@ private void closeSwitchBlock(Block block, Block dom) {
private boolean isNestedIfNode(Block block) {
final Block dom = block.getDominator();
boolean isMerge = block.getBeginNode() instanceof MergeNode;

boolean sameDominator = isMerge;
if (isMerge) {
MergeNode mergeNode = (MergeNode) block.getBeginNode();
NodeMap<Block> nodeToBlockMap = mergeNode.graph().getLastSchedule().getNodeToBlockMap();
for (EndNode predecessor : mergeNode.cfgPredecessors()) {
if (nodeToBlockMap.get(predecessor).getDominator() != dom) {
sameDominator = false;
break;
}
}
}

boolean isReturn = block.getEndNode() instanceof ReturnNode;
return dom != null && isMerge && isReturn && !dom.isLoopHeader() && isIfBlock(dom);
return dom != null && isMerge && sameDominator && isReturn && !dom.isLoopHeader() && isIfBlock(dom);
}

private boolean isIfBlockNode(Block block) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLControlFlow.LoopConditionOp;
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLControlFlow.LoopInitOp;
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLControlFlow.LoopPostOp;
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLLIRStmt;
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLLIRStmt.AssignStmt;

public class OCLCompilationResultBuilder extends CompilationResultBuilder {
Expand Down Expand Up @@ -264,6 +265,29 @@ void emitLoopBlock(Block block) {
emitBlock(block);
}

void emitRelocatedInstructions(Block block) {
if (block == null) {
return;
}

trace("block on exit %d", block.getId());

boolean relocatableInstruction = false;
for (LIRInstruction op : lir.getLIRforBlock(block)) {
if (op instanceof OCLLIRStmt.MarkRelocateInstruction) {
relocatableInstruction = true;
}

if (op != null && relocatableInstruction) {
try {
emitOp(this, op);
} catch (TornadoInternalError e) {
throw e.addContext("lir instruction", block + "@" + op.id() + " " + op + "\n");
}
}
}
}

void emitBlock(Block block) {
if (block == null) {
return;
Expand All @@ -274,8 +298,13 @@ void emitBlock(Block block) {

LIRInstruction breakInst = null;

boolean relocatableInstruction = false;
for (LIRInstruction op : lir.getLIRforBlock(block)) {
if (op == null) {
if (op instanceof OCLLIRStmt.MarkRelocateInstruction) {
relocatableInstruction = true;
}

if (op == null || relocatableInstruction) {
continue;
} else if (op instanceof OCLControlFlow.LoopBreakOp) {
breakInst = op;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ private void emitLoopBegin(final LoopBeginNode loopBeginNode) {
*/
setResult(phi, value);
} else {
final AllocatableValue result = (AllocatableValue) operandForPhi(phi);
final AllocatableValue result = gen.asAllocatable(operandForPhi(phi));
append(new OCLLIRStmt.AssignStmt(result, value));
}
}
Expand Down Expand Up @@ -683,6 +683,30 @@ public void visitEndNode(final AbstractEndNode end) {
return;
}

// Move the phi assignment outside the loop.
// Only do that for the phi nodes that are not inside "else { break; }" blocks.
Block curBlock = (Block) gen.getCurrentBlock();
boolean shouldRelocateInstructions = false;
if (curBlock.getBeginNode() instanceof LoopExitNode) {
LoopExitNode loopExitNode = (LoopExitNode) curBlock.getBeginNode();
LoopBeginNode loopBeginNode = loopExitNode.loopBegin();
Block loopBeginBlock = loopBeginNode.graph().getLastSchedule().getNodeToBlockMap().get(loopBeginNode);
for (Block pred : curBlock.getPredecessors()) {
if (pred == loopBeginBlock) {
shouldRelocateInstructions = true;
break;
}
}
}

/*
* It generates instructions that are relocated from within the for-loop to after the for-loop.
* https://github.com/beehive-lab/TornadoVM/pull/129
*/
if (shouldRelocateInstructions) {
append(new OCLLIRStmt.MarkRelocateInstruction());
}

final AbstractMergeNode merge = end.merge();
for (ValuePhiNode phi : merge.valuePhis()) {
final ValueNode value = phi.valueAt(end);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ public final void emitCode(CompilationResultBuilder crb) {

}

@Opcode("MARK_RELOCATE")
public static class MarkRelocateInstruction extends AbstractInstruction {

public static final LIRInstructionClass<MarkRelocateInstruction> TYPE = LIRInstructionClass.create(MarkRelocateInstruction.class);

public MarkRelocateInstruction() {
super(TYPE);
}

@Override
public void emitCode(OCLCompilationResultBuilder crb, OCLAssembler asm) {
// No code is generated
}
}

@Opcode("ASSIGN")
public static class AssignStmt extends AbstractInstruction {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Arrays;
import java.util.stream.IntStream;

import org.junit.Ignore;
import org.junit.Test;

import uk.ac.manchester.tornado.api.TaskSchedule;
Expand Down Expand Up @@ -108,6 +109,7 @@ public void test02() {
}

@Test
@Ignore
public void test03() {
if (isRunningOnCPU()) {
return;
Expand Down

0 comments on commit 0463f8b

Please sign in to comment.