From 4ea02c59d8c9223cae9eab7ae0ab1d3e42702554 Mon Sep 17 00:00:00 2001 From: "james.brodman" Date: Tue, 21 May 2013 10:00:22 -0400 Subject: [PATCH 1/2] Disable break optimization and change return check to use full mask. --- ctx.cpp | 2 +- stmt.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ctx.cpp b/ctx.cpp index 872751eb..5b93c8bc 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -1266,7 +1266,7 @@ FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) { LoadInst(returnedLanesPtr, "old_returned_lanes"); llvm::Value *newReturnedLanes = BinaryOperator(llvm::Instruction::Or, oldReturnedLanes, - GetInternalMask(), "old_mask|returned_lanes"); + GetFullMask(), "old_mask|returned_lanes"); // For 'coherent' return statements, emit code to check if all // lanes have returned diff --git a/stmt.cpp b/stmt.cpp index a95f8fbf..eba506ab 100644 --- a/stmt.cpp +++ b/stmt.cpp @@ -447,6 +447,8 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const { ctx->SetCurrentBasicBlock(bexit); ctx->EndIf(); } + /* + // Disabled for performance reasons. Change to an optional compile-time opt switch. else if (lCanApplyBreakOptimization(trueStmts, falseStmts)) { // If we have a simple break statement inside the 'if' and are // under varying control flow, just update the execution mask @@ -456,6 +458,7 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const { // benefit in this case. ctx->SetInternalMaskAndNot(ctx->GetInternalMask(), testValue); } + */ else emitVaryingIf(ctx, testValue); } From 403d9e105913512969cc86ed061bb6657f6670f8 Mon Sep 17 00:00:00 2001 From: "james.brodman" Date: Tue, 21 May 2013 10:52:38 -0400 Subject: [PATCH 2/2] Update break/continue test to use contribution of function mask. --- ctx.cpp | 7 +++++++ stmt.cpp | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ctx.cpp b/ctx.cpp index 5b93c8bc..b7691f15 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -841,6 +841,9 @@ FunctionEmitContext::jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target) { if (breakLanesPtr == NULL) { llvm::Value *continued = LoadInst(continueLanesPtr, "continue_lanes"); + continued = BinaryOperator(llvm::Instruction::And, + continued, GetFunctionMask(), + "continued&func"); allDone = MasksAllEqual(continued, blockEntryMask); } else { @@ -860,6 +863,10 @@ FunctionEmitContext::jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target) { finishedLanes = BinaryOperator(llvm::Instruction::Or, finishedLanes, continued, "returned|breaked|continued"); } + + finishedLanes = BinaryOperator(llvm::Instruction::And, + finishedLanes, GetFunctionMask(), + "finished&func"); // Do we match the mask at loop or switch statement entry? allDone = MasksAllEqual(finishedLanes, blockEntryMask); diff --git a/stmt.cpp b/stmt.cpp index eba506ab..4ec63d35 100644 --- a/stmt.cpp +++ b/stmt.cpp @@ -374,6 +374,7 @@ lEmitIfStatements(FunctionEmitContext *ctx, Stmt *stmts, const char *trueOrFalse /** Returns true if the "true" block for the if statement consists of a single 'break' statement, and the "false" block is empty. */ +/* static bool lCanApplyBreakOptimization(Stmt *trueStmts, Stmt *falseStmts) { if (falseStmts != NULL) { @@ -392,7 +393,7 @@ lCanApplyBreakOptimization(Stmt *trueStmts, Stmt *falseStmts) { else return false; } - +*/ void IfStmt::EmitCode(FunctionEmitContext *ctx) const {