Skip to content

Commit

Permalink
Modified OpenCL generator to forward declare all variables. (#1084)
Browse files Browse the repository at this point in the history
  • Loading branch information
MoFtZ authored Sep 7, 2023
1 parent d1dee9f commit 8a8f825
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 17 deletions.
63 changes: 56 additions & 7 deletions Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public struct StatementEmitter : IDisposable
#region Instance

private readonly StringBuilder stringBuilder;
private readonly StringBuilder variableBuilder;
private bool argMode;
private int argumentCount;

Expand All @@ -58,6 +59,7 @@ internal StatementEmitter(CLCodeGenerator codeGenerator)
{
CodeGenerator = codeGenerator;
stringBuilder = codeGenerator.Builder;
variableBuilder = codeGenerator.VariableBuilder;
argumentCount = 0;
argMode = false;

Expand Down Expand Up @@ -85,20 +87,23 @@ internal StatementEmitter(CLCodeGenerator codeGenerator)
private void BeginAppendTarget(Variable target, bool appendNew = true)
{
if (appendNew)
{
var variableType = CodeGenerator.GetVariableType(target);
stringBuilder.Append(variableType);
stringBuilder.Append(' ');
}
AppendDeclaration(target);
stringBuilder.Append(target.ToString());
}

/// <summary>
/// Appends a target declaration.
/// </summary>
/// <param name="target">The target declaration.</param>
internal void AppendDeclaration(Variable target) =>
BeginAppendTarget(target);
internal void AppendDeclaration(Variable target)
{
var variableType = CodeGenerator.GetVariableType(target);
variableBuilder.Append('\t');
variableBuilder.Append(variableType);
variableBuilder.Append(' ');
variableBuilder.Append(target.ToString());
variableBuilder.AppendLine(";");
}

/// <summary>
/// Appends a target.
Expand Down Expand Up @@ -827,6 +832,50 @@ public StatementEmitter BeginStatement(FormattableString command)
return emitter;
}

/// <summary>
/// Begins the function body, switching to variable capturing mode.
/// </summary>
protected void BeginFunctionBody()
{
// Start the function body.
Builder.AppendLine("{");
PushIndent();

#if DEBUG
Builder.AppendLine();
Builder.AppendLine("\t// Variable declarations");
Builder.AppendLine();
#endif

// Switch to the alternate builder, so that we can capture the code and
// variable declarations separately.
prefixBuilder = Builder;
Builder = suffixBuilder;
}

/// <summary>
/// Finishes the function body, ending variable capturing mode.
/// </summary>
protected void FinishFunctionBody()
{
// Restore the original builder, containing code before the variable
// declarations.
Builder = prefixBuilder;

// Add the variable declarations at the start of the function, to avoid
// issues with OpenCL compilers that are not C99 compliant, and cannot
// handle variable declarations intermingled with other code.
Builder.Append(VariableBuilder);
Builder.AppendLine();

// Add the code that was generated along with the variable declarations.
Builder.Append(suffixBuilder);

// Close the function body.
PopIndent();
Builder.AppendLine("}");
}

#endregion
}
}
12 changes: 10 additions & 2 deletions Src/ILGPU/Backends/OpenCL/CLCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ protected static string GetParameterName(Parameter parameter) =>
new Dictionary<BasicBlock, string>();
private readonly string labelPrefix;

private StringBuilder prefixBuilder = new StringBuilder();
private StringBuilder suffixBuilder = new StringBuilder();

/// <summary>
/// Constructs a new code generator.
/// </summary>
Expand All @@ -218,7 +221,7 @@ internal CLCodeGenerator(in GeneratorArgs args, Method method, Allocas allocas)

labelPrefix = "L_" + Method.Id.ToString();

Builder = new StringBuilder();
Builder = prefixBuilder;
}

#endregion
Expand Down Expand Up @@ -250,7 +253,12 @@ public IntrinsicImplementationProvider<CLIntrinsic.Handler>
/// <summary>
/// Returns the associated string builder.
/// </summary>
public StringBuilder Builder { get; }
public StringBuilder Builder { get; private set; }

/// <summary>
/// Returns the associated string builder.
/// </summary>
public StringBuilder VariableBuilder { get; } = new StringBuilder();

#endregion

Expand Down
6 changes: 2 additions & 4 deletions Src/ILGPU/Backends/OpenCL/CLFunctionGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,9 @@ public override void GenerateCode()
BindSharedMemoryAllocation(Allocas.DynamicSharedAllocations);

// Generate code
Builder.AppendLine("{");
PushIndent();
BeginFunctionBody();
GenerateCodeInternal();
PopIndent();
Builder.AppendLine("}");
FinishFunctionBody();
}

#endregion
Expand Down
6 changes: 2 additions & 4 deletions Src/ILGPU/Backends/OpenCL/CLKernelFunctionGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,7 @@ public override void GenerateCode()
Builder.AppendLine(")");

// Emit code that moves view arguments into their appropriate targets
Builder.AppendLine("{");
PushIndent();
BeginFunctionBody();
GenerateArgumentMapping();

// Emit index computation
Expand Down Expand Up @@ -323,8 +322,7 @@ public override void GenerateCode()

// Generate code
GenerateCodeInternal();
PopIndent();
Builder.AppendLine("}");
FinishFunctionBody();
}

/// <summary>
Expand Down

0 comments on commit 8a8f825

Please sign in to comment.