private void GenerateBasicBlocks(Class newClass, ZMethod zMethod)
{
//
// Split the method into basic blocks, and then do code generation
// based on this analysis
//
if (labelString != null)
basicBlockToLabel = new Hashtable();
List<BasicBlock> basicBlocks = BBSplitter.SplitMethod(zMethod, this);
if (labelString != null)
{
string methodName = zMethod.FullName;
int index = methodName.IndexOf('(');
if (index < 0)
AddToLabelString(methodName);
else
{
Debug.Assert(index > 0);
AddToLabelString(methodName.Substring(0, index));
}
}
//
// Look for opportunities to combine or remove blocks
//
// NOTE: this breaks summarization because it removes "transition" blocks
// around atomic regions that they rely on.
//
//basicBlocks = BBOptimizer.Optimize(basicBlocks);
EnumNode enumNode = (EnumNode)Templates.GetMemberByName(newClass.Members, "Blocks");
Field entryPointField = (Field)enumNode.Members[1];
int nextBlockEnumValue = 2;
// Accumulate a list of scopes for which we've generated cleanup methods. These are
// scopes that contain pointers.
List<Scope> nonTrivialScopes = new List<Scope>();
foreach (BasicBlock block in basicBlocks)
{
if (!nonTrivialScopes.Contains(block.Scope) && ScopeNeedsCleanup(block.Scope))
{
nonTrivialScopes.Add(block.Scope);
AddScopeCleanupMethod(newClass, block.Scope);
}
}
foreach (BasicBlock block in basicBlocks)
{
// Add the blocks to the Blocks enum
if (!block.IsEntryPoint)
{
Field f = new Field(enumNode, null, entryPointField.Flags,
new Identifier(block.Name), entryPointField.Type, null);
f.Initializer = new Literal(nextBlockEnumValue++, SystemTypes.UInt16);
enumNode.Members.Add(f);
}
// Emit a method for this block
AddBlockMethod(zMethod, newClass, block, nonTrivialScopes);
}
PatchDispatchMethod(newClass, basicBlocks);
PatchRunnableMethod(newClass, basicBlocks);
PatchIsAtomicEntryMethod(newClass, basicBlocks);
PatchValidEndStateProperty(newClass, basicBlocks);
PatchSourceContextProperty(zMethod, newClass, basicBlocks);
PatchContextAttributeProperty(zMethod, newClass, basicBlocks);
}