static void PreOptimize( void ) /*****************************************/ { bool change; if( _IsntModel( NO_OPTIMIZATION ) ) { // CharsAndShortsToInts(); MakeMovAddrConsts(); PushPostOps(); DeadTemps(); InsDead(); MakeFlowGraph(); BlockTrim(); CommonSex( _IsModel( LOOP_OPTIMIZATION ) ); SetOnCondition(); BlockTrim(); AddANop(); if( _IsModel( LOOP_OPTIMIZATION ) ) { change = FALSE; if( TransLoops( FALSE ) ) { change = TRUE; } if( LoopInvariant() ) { change = TRUE; } if( change ) { CommonSex(TRUE); InsDead(); CommonInvariant(); } if( IndVars() ) { CommonSex(FALSE); InsDead(); change = TRUE; } BlockTrim(); if( TransLoops( TRUE ) ) { BlockTrim(); CommonSex( FALSE ); change = TRUE; } if( change ) { ReConstFold(); } LoopEnregister(); if( change ) { BlockTrim(); } } MulToShiftAdd(); KillMovAddrConsts(); FindReferences(); } else { MakeFlowGraph(); AddANop(); FindReferences(); } }
extern void TempStrategy() { /******************************* Figure out whether we will have any auto variables, parms which aren't within 4K of the AR register, and turn references to these temporaries into indexed references. Look only for autos that have complicated lives. */ name *temp; type_length temp_size; temp_size = 0; NoseInAdded = FALSE; NoseIn = NULL; if( CurrProc->state.attr & ROUTINE_OS ) { CurrProc->parms.size = 0; } else { CurrProc->parms.size = CurrProc->state.parm.offset; } FindReferences(); for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) { if( temp->t.temp_flags & ALIAS ) continue; if( temp->t.temp_flags & STACK_PARM ) continue; if( temp->v.usage & USE_IN_ANOTHER_BLOCK ) { temp_size += temp->n.size; } } if( temp_size + CurrProc->parms.size <= SAFE ) { /* don't worry, be happy */ } else { if( temp_size <= SAFE || CurrProc->parms.size > 100 ) { CurrProc->state.attr |= ROUTINE_ALTERNATE_AR; ThrowOutParms(); FixFarLocalRefs( CurrProc->parms.size ); AdjustConsts( -CurrProc->parms.size ); } if( temp_size > SAFE ) { SortTemps(); ThrowOutBigTemps( temp_size ); CountTempRefs(); AddAliasRefs(); OnTheEdge(); AllocFarLocals(); FixFarLocalRefs( CurrProc->targ.far_local_size ); } } }
extern void SplitVars( void ) /*******************************/ /* For each variable, find out if it can be split into two separate variables.*/ /* This often happens when programmers re-use variables rather than defining*/ /* a new one.*/ { name *op; conflict_node *conf; for( ;; ) { for( conf = ConfList; conf != NULL; conf = conf->next_conflict ) { op = conf->name; if( (op->v.usage & USE_IN_ANOTHER_BLOCK) == 0 ) continue; if( op->n.class != N_TEMP ) continue; if( _Is( conf, CST_CONF_VISITED ) ) continue; _SetFalse( conf, CST_CONFLICT_ON_HOLD ); if( _GBitEmpty( conf->id.out_of_block ) ) continue; if( op->t.alias == op ) Split1Var( conf ); _GBitInit( conf->id.out_of_block, EMPTY ); _SetTrue( conf, CST_CONFLICT_ON_HOLD | CST_CONF_VISITED ); } if( !MoreConflicts() ) { break; } } CleanUp(); FreeConflicts(); InsDead(); NullConflicts( EMPTY ); FindReferences(); MakeConflicts(); }
std::vector<AssetReference> IAsset::FindReferencesRecursive() const { std::set<AssetReference> refs; std::vector<AssetReference> unwalkedRefs = FindReferences(); while(unwalkedRefs.size() > 0) { AssetReference ref = unwalkedRefs.back(); unwalkedRefs.pop_back(); if (refs.find(ref) == refs.end()) { refs.insert(ref); AssetPtr asset = assetAPI->GetAsset(ref.ref); if (asset) { std::vector<AssetReference> newRefs = asset->FindReferences(); unwalkedRefs.insert(unwalkedRefs.end(), newRefs.begin(), newRefs.end()); } } } std::vector<AssetReference> finalRefs(refs.begin(), refs.end()); return finalRefs; }
static void BlockToCode( bool partly_done ) /*********************************************/ { block_num inputs; block_num targets; block_edge *input_edges; conflict_node *curr; conflict_node **owner; conflict_node *conflist; block_num id; /* try to get back some memory*/ _MemLow; /* make the block look like an entire procedure*/ HeadBlock = CurrBlock; BlockList = CurrBlock; HeadBlock->prev_block = NULL; if( HeadBlock->next_block != NULL ) { HeadBlock->next_block->prev_block = NULL; } /* Kludge - need a pointer to the next block for CALL_LABEL - puke! */ if( HeadBlock->class & CALL_LABEL ) { HeadBlock->v.next = HeadBlock->next_block; } HeadBlock->next_block = NULL; /* force anything that spans blocks to memory */ HeadBlock->u.partition = HeadBlock; ConstFold( HeadBlock ); HeadBlock->u.partition = NULL; ForceTempsMemory(); if( partly_done == FALSE ) { FixMemRefs(); HaveLiveInfo = FALSE; if( _IsntModel( NO_OPTIMIZATION | FORTRAN_ALIASING ) ) { FindReferences(); CommonSex(FALSE); PushPostOps(); } FindReferences(); DeadTemps(); if( _IsModel( NO_OPTIMIZATION ) ) { SetInOut( HeadBlock ); } else { MakeConflicts(); } MakeLiveInfo(); HaveLiveInfo = TRUE; AxeDeadCode(); FixIndex(); FixSegments(); FPRegAlloc(); RegAlloc( TRUE ); FreeConflicts(); HaveLiveInfo = FALSE; } else { conflist = NULL; owner = &ConfList; for( ;; ) { curr = *owner; if( curr == NULL ) break; if( curr->start_block == HeadBlock ) { *owner = curr->next_conflict; curr->next_conflict = conflist; conflist = curr; } else { owner = &curr->next_conflict; } } curr = ConfList; ConfList = conflist; RegAlloc( TRUE ); FreeConflicts(); ConfList = curr; } input_edges = HeadBlock->input_edges; inputs = HeadBlock->inputs; targets = HeadBlock->targets; HeadBlock->inputs = 0; HeadBlock->input_edges = NULL; HeadBlock->targets = 0; FPParms(); PostOptimize(); HeadBlock->input_edges = input_edges; HeadBlock->inputs = inputs; HeadBlock->targets = targets; /* generate a prolog that saves all registers*/ if( ( CurrProc->prolog_state & GENERATED_PROLOG ) == 0 ) { CurrProc->state.used = AllCacheRegs(); GenProlog(); } id = CurrBlock->id; AssgnMoreTemps( id ); OptSegs(); /* generate the code for the block*/ if( CurrBlock->class & RETURN ) { GenObject(); FiniStackMap(); FreeProc(); } else {