// Build pointer assignment graph
ContextInsensitiveBuilder b = new ContextInsensitiveBuilder();
if( opts.pre_jimplify() ) b.preJimplify();
if( opts.force_gc() ) doGC();
Date startBuild = new Date();
final PAG pag = b.setup( opts );
b.build();
Date endBuild = new Date();
reportTime( "Pointer Assignment Graph", startBuild, endBuild );
if( opts.force_gc() ) doGC();
// Build type masks
Date startTM = new Date();
pag.getTypeManager().makeTypeMask();
Date endTM = new Date();
reportTime( "Type masks", startTM, endTM );
if( opts.force_gc() ) doGC();
if( opts.verbose() ) {
G.v().out.println( "VarNodes: "+pag.getVarNodeNumberer().size() );
G.v().out.println( "FieldRefNodes: "+pag.getFieldRefNodeNumberer().size() );
G.v().out.println( "AllocNodes: "+pag.getAllocNodeNumberer().size() );
}
// Simplify pag
Date startSimplify = new Date();
// We only simplify if on_fly_cg is false. But, if vta is true, it
// overrides on_fly_cg, so we can still simplify. Something to handle
// these option interdependencies more cleanly would be nice...
if( ( opts.simplify_sccs() && !opts.on_fly_cg() ) || opts.vta() ) {
new SCCCollapser( pag, opts.ignore_types_for_sccs() ).collapse();
}
if( opts.simplify_offline() && !opts.on_fly_cg() ) {
new EBBCollapser( pag ).collapse();
}
if( true || opts.simplify_sccs() || opts.vta() || opts.simplify_offline() ) {
pag.cleanUpMerges();
}
Date endSimplify = new Date();
reportTime( "Pointer Graph simplified", startSimplify, endSimplify );
if( opts.force_gc() ) doGC();