Skip to content

Commit

Permalink
cleanup output
Browse files Browse the repository at this point in the history
  • Loading branch information
ailrst committed Nov 29, 2023
1 parent 0fe3041 commit 0fd434d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 27 deletions.
44 changes: 21 additions & 23 deletions docs/il-cfg.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ We need to derive the predecessor/successor relation on CFG nodes IL .

1. CFG positions are defined as
- The entry to a procedure
- An exit from a procedure
- The single return point from a procedure
- The beginning of a block within a procedure
- A statement command within a block
- A jump or call command within a block
Expand All @@ -44,6 +44,9 @@ First we have basic blocks belonging to a procedure.

Procedure(id)
Block(id, procedure)
EntryBlock(block_id, procedure)
ReturnBlock(block_id, procedure)
Block(id, procedure) :- EntryBlock(id, procedure); ReturnBlock(id, procedure)

A list of sequential statements belonging to a block

Expand All @@ -52,24 +55,17 @@ A list of sequential statements belonging to a block
A list of jumps (either Calls or GoTos) belonging to a block, which occur after the statements. GoTos form the
intra-procedural edges, and Calls form the inter-procedural edges.

GoTo(id, block, index, destinationBlock)
Call(id, block, index, destinationProcedure)
Jump(id, block) :- GoTo(id, block, _) ; Call(id, block, _)
GoTo(id, block, destinationBlock) // multiple destinations
Call(id, block, destinationProcedure, returnBlock), count {Call(id, block, _, _)} == 1
Jump(id, block) :- GoTo(id, block, _) ; Call(id, block, _, _)

Statements and Jumps are both considered commands. All IL terms, commands, blocks, and procedures, have a unique
identifier. All of the above are considered IL terms.

Command(id) :- Statement(id, _, _) ; Jump(id, _)
ILTerm(id) :- Procedure(id); Block(id, _); Command(id)

The CFG extends this language with the following nodes:

ProcedureExit(id, fromProcedure, fromJump)
CallReturn(id, fromCall)

CFGNode(id) :- ProcedureExit(id,_,_) ; CallReturn(id,_) ; ILTerm(id)

The predecessor/successor relates CFGNodes to CFGNodes, and is simply defined in terms of the nodes
The predecessor/successor relates ILTerms to ILTerms, and is simply defined in terms of the nodes

pred(i, j) :- succ(j, i)

Expand All @@ -79,15 +75,11 @@ The predecessor/successor relates CFGNodes to CFGNodes, and is simply defined in

succ(goto, targetBlock) :- GoTo(goto, _, _, targetBlock)

// We always insert nodes for calls to return to
CallReturn(i, call) :- Call(call, _, _, _)
succ(call, callreturn) :- CallReturn(callreturn, call), Procedure(call)

// a 'return' from the procedure is an indirect call to register R30
succ(call, exit) :- Call(call, block, _, "R30"), ProcedureExit(exit, procedure, call), Block(block, procedure)
succ(call, return_block) :- Call(call, block, dest_procedure, return_block)

For an inter-procedural CFG we also have:

succ(call, return_block) :- ReturnBlock(return_block, call), Procedure(call)
succ(call, targetProcedure) :- Call(call, _, _, targetProcedure)
succ(exit, returnNode) :- ProcedureExit(exit, procedure, call), CallReturn(returnNode, call)

Expand Down Expand Up @@ -128,11 +120,17 @@ Specifically this means we store
- list of incoming Calls
- subroutine to compute the set of all outgoing calls in all contained blocks

To maintain this superimposed graph it is necessary to make the actual call lists private, and only allow
modification of through interfaces which maintain the graph.

Maintenance of the graph is the responsibility of the Block class: adding or removing jumps must ensure the edge
references are maintained.
This means the IL contains:
- Forward graph edges in the forms of calls and gotos
- Forward syntax tree edges in the form of classes containing their children as fields
- Backwards graph edges in the form of lists of incoming jumps and calls
- Procedure has list of incoming calls
- Block has list of incoming gotos
- Backwards syntax tree edges in the form of a parent field
- Implementation of the `HasParent` trait.

To maintain the backwards edges it is necessary to make the actual data structures private, and only allow
modification through interfaces which maintain the graph/tree.

Jumps:
- Must implement an interface to allow adding or removing edge references (references to themself) to and from their
Expand Down
9 changes: 5 additions & 4 deletions src/main/scala/util/RunUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,10 @@ object RunUtils {
isEntryNode = false
printNode(c)
case c: Command =>
//if (c.parent.label != previousBlock) {
// printBlock(c.parent)
//}
if (c.parent.label != previousBlock) {
printBlock(c.parent)
}
s.append(" ")
printNode(c)
previousBlock = c.parent.label
isEntryNode = false
Expand Down Expand Up @@ -280,7 +281,7 @@ object RunUtils {
node match {
case _: Statement => s.append("[Stmt] ")
case _: Procedure => s.append("[FunctionEntry] ")
case _: Call => s.append("[Jmp] ")
case _: Jump => s.append("[Jmp] ")
case _ => ()
}

Expand Down

0 comments on commit 0fd434d

Please sign in to comment.