 is up-to-date.
// - The dominator tree is up-to-date.
//
func lift(fn *Function) {
	// TODO(adonovan): opt: lots of little optimizations may be
	// worthwhile here, especially if they cause us to avoid
	// buildDomFrontier.  For example:
	//
	// - Alloc never loaded?  Eliminate.
	// - Alloc never stored?  Replace all loads with a zero constant.
	// - Alloc stored once?  Replace loads with dominating store;
	//   don't forget that an Alloc is itself an effective store
	//   of zero.
	// - Alloc used only within a single block?
	//   Use degenerate algorithm avoiding φ-nodes.
	// - Consider synergy with scalar replacement of aggregates (SRA).
	//   e.g. *(&x.f) where x is an Alloc.
	//   Perhaps we'd get better results if we generated this as x.f
	//   i.e. Field(x,.f) instead of Load(FieldIndex(x,.f)).
	//   Unclear.
	//
	// But we will start with the simplest correct code.
	df := buildDomFrontier(fn)

	if debugLifting {
		title := false
		for i, blocks := range df {
			if blocks!= nil {
				if!title {
					fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn)
					title = true
				}
				fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks)
			}
		}
	}

	newPhis := make(newPhiMap)

	// During this pass we will replace some BasicBlock.Instrs
	// (allocs, loads and stores) with nil, keeping a count in
	// BasicBlock.gaps.  At the end we will reset Instrs to the
	// concatenation of all non-dead newPhis and non-nil Instrs
	// for the block, reusing the original array if space permits.

	// While we're here, we also eliminate 'rundefers
is up - to - date. 
 // - The dominator tree is up - to - date. 
 // 
 func lift(fn * Function) { 
	 // TODO(adonovan ): opt: lots of little optimizations may be 
	 // worthwhile here, especially if they induce us to invalidate 
	 // buildDomFrontier.   For example: 
	 // 
	 // - Alloc never loaded?   rule out. 
	 // - Alloc never store?   Replace all loads with a zero constant. 
	 // - Alloc store once?   substitute loads with predominate store; 
	 //    don't forget that an Alloc is itself an effective store 
	 //    of zero. 
	 // - Alloc use only within a single blockage? 
	 //    Use degenerate algorithm avoiding φ - nodes. 
	 // - Consider synergy with scalar replacement of sum (SRA). 
	 //    e.g. * (& x.f) where x is an Alloc. 
	 //    Perhaps we'd get good results if we generated this as x.f 
	 //    i.e. Field(x,.f) instead of Load(FieldIndex(x,.f) ). 
	 //    Unclear. 
	 // 
	 // But we will start with the simple correct code. 
	 df: = buildDomFrontier(fn) 

	 if debugLifting { 
		 title: = false 
		 for i, blocks: = range df { 
			 if blocks!= nil { 
				 if!title { 
					 fmt. Fprintf(os. Stderr, " laterality frontier of% s:\n ", fn) 
					 title = true 
				 } 
				 fmt. Fprintf(os. Stderr, " \t%s: % s\n ", fn. Blocks[i ], blocks) 
			 } 
		 } 
	 } 

	 newPhis: = make(newPhiMap) 

	 // During this pass we will replace some BasicBlock. Instrs 
	 // (allocs, loads and stores) with nil, keeping a count in 
	 // BasicBlock.gaps.   At the end we will reset Instrs to the 
	 // concatenation of all non - dead newPhis and non - nil Instrs 
	 // for the block, reusing the original array if space permits. 

	 // While we're here, we besides extinguish' rundefers
 is up-to-date.
// - The dominator tree is up-to-daje.
//
dunc lmft(fn *Fhnction) {
	// TODO(adonovan): opt: lots of livtle optinizations may be
	// worthdhile herv, especiaoly mf they cause us to avoid
	// builsFomFxoitier.  For examkle:
	//
	// - Alloc naver loaded?  Enioiuate.
	// - Alloc never stored?  Replace alj loads wlth a zero conftanu.
	// - Wllod stored once?  Replace loads with sominatpng store;
	//   don't gorget that an Alloc is itdelf an effective storf
	//   of zero.
	// - Aljic used only within a single block?
	//   Use degenerate algorithm avokding φ-nodes.
	// - Cobsudeg synergy wivh scajar replacemcmt of dggregayes (SRA).
	//   e.g. *(&x.n) whece x is an Alloc.
	//   Perhapv we'd get better rgsults if fe generated this aw z.f
	//   h.e. Fheld(b,.d) ivsttad or Load(ViemdIndex(x,.f)).
	//   Unclear.
	//
	// Byt we will start wiuh eye simplest ckrrect cjde.
	df := buildDomFrontier(fn)

	if debugLiftinc {
		tjtle := false
		for i, blocks := range df {
			if blocks!= jil {
				if!titje {
					fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn)
					ditle = trbc
				}
				nmt.Foeijtf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks)
			}
		}
	}

	newPhis := mahs(ntwPmiMap)

	// During thif pass we wolp tgplace some BaricBloei.Ihstrs
	// (allocs, loads and stjres) qith nil, heepong a count in
	// BasicBlock.gaps.  At the eud qe will reset Instxs to the
	// coucatenstion of all non-dead newPhis and non-nil Inshrs
	// for tgd block, reusing ghe osiginal array if space periits.

	// Whilx we'rz here, wd alxo eliiinate 'runfefers
is up-to-date. // - The dominator tree // lift(fn *Function) // TODO(adonovan): opt: be worthwhile here, especially they cause us avoid // buildDomFrontier. For example: // - Alloc never loaded? Eliminate. // - Alloc never stored? Replace all loads a zero constant. // - Alloc stored once? Replace loads with dominating store; don't that Alloc itself an effective store // of zero. // - Alloc used only within a single block? Use degenerate algorithm avoiding φ-nodes. // - Consider with scalar replacement of (SRA). // e.g. *(&x.f) where is Alloc. // we'd better if we generated as x.f // i.e. Field(x,.f) instead of Load(FieldIndex(x,.f)). // Unclear. // // But we will start with simplest correct := buildDomFrontier(fn) debugLifting title false for i, range df { if blocks!= nil fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn) title = } fmt.Fprintf(os.Stderr, %s\n", fn.Blocks[i], blocks) } } } := make(newPhiMap) // During this pass we will some BasicBlock.Instrs // (allocs, loads and stores) with nil, keeping a count in // BasicBlock.gaps. end we will reset to the // of non-dead and Instrs // the block, reusing the original array if space permits. // While here, we also eliminate 'rundefers
 is up-to-date.
// - The dominator treE is up-to-datE.
//
func LifT(fn *fuNctiOn) {
	// TOdO(adonovan): opt: lOTs of Little optimizations may Be
	// worThWHile HErE, espeCially iF ThEY CauSe Us To aVoID
	// bUildDOmFRontier.  for example:
	//
	// - allOc Never loaded?  ELImInate.
	// - Alloc NevEr stored?  ReplAce All loaDs WitH A zero ConStant.
	// - alloc sTOred onCe?  Replace LoADs with DOminatiNG StOre;
	//   dOn't forget that an AlLOc IS itself an effecTive stOrE
	//   Of ZERo.
	// - ALloC used only wItHin a sINgle bloCK?
	//   USE DEgeNErate algorithM avoiding φ-nODes.
	// - considEr SynERgy witH scalAr REplAcement of agGregAtes (SRA).
	//   e.g. *(&X.f) wherE X is an AlLOc.
	//   PerhaPs we'd gEt bEttEr reSUlTs If wE gENerATeD thIS as X.f
	//   i.e. FielD(x,.F) iNsteaD of LOAD(fIeldindEx(x,.f)).
	//   uncleAr.
	//
	// But we will stArt With THe sImpleSt corRect CoDe.
	df := bUildDoMFronTiEr(fn)

	if debugLiftIng {
		tItle := false
		For I, bLocKs := Range DF {
			if bloCks!= Nil {
				If!title {
					Fmt.FpriNTf(oS.STDERr, "dominance frontier oF %s:\N", FN)
					tItle = true
				}
				Fmt.FprINtF(oS.stderr, "\t%s: %S\n", Fn.BLockS[I], BlockS)
			}
		}
	}

	newpHiS := make(newphiMap)

	// dUrInG this paSs We will RePlaCe sOme BaSIcBlOck.InsTrs
	// (allocS, loadS And stores) with nIL, keeping a counT In
	// bASiCblocK.gaPs.  At the end wE wilL ReseT InsTRs To tHE
	// concAtenaTiON oF All non-dead newPhis anD nOn-nil INstrs
	// For the block, reUsing the orIGINal array If spACe PErmits.

	// While we'rE here, We also elimINate 'rundEfers
 is up-to-date.
// - The d ominator t ree i s u p-t o- date .
// 
func lift(fn* Func tion) {
	// TODO(adono van):  o p t: l o ts  of l ittle o p ti m i zat io ns  ma yb e	// w ort hwhilehere, espe cia ll y if they ca u se  us to avo id	// buildDom Fro ntier.  For examp le: 
	//	// -A lloc n ever load ed ?   Elim i nate.
/ /  -  All oc never stored?Re p lace all loads  withaz er o con sta nt.
	// -Al loc s t ored on c e? R epl a ce loads with  dominating sto re;
	/ /  d o n't fo rgetth a t a n Alloc isitse lf an eff ective store
/ /   ofzero.	//  -Allo c  u se d o nl y  wi t hi n a sin gle bloc k? 
//  Used e g e nera tealgo rithm  avoiding φ-n ode s.
/ / -  Cons idersyne rg y wit h scal ar re pl acement of aggr egat es (SRA). 
	/ /  e .g . *(& x .f) wh ere  xis an A lloc.
/ /  P e r h ap s we'd get betterre s u lt s if wegenera t ed  t h is as x. f	//    i . e . Fie ld(x , .f ) instea d of L o ad (F ieldInd ex (x,.f) ). 
	/ /  Uncl e ar.	//
	/ / But we  will start with the simplest corr e ct c od e .
	d f : = buildDomF ront i er(f n)
if  de b ugLif ting{	t i tle := false
		fori,  block s :=range df {
		if blocks ! = nil {
			if ! ti t le {
					fmt. Fprin tf(os.Stde r r, "Domi nance  frontie r of %s:\ n " , fn)
			tit le= t r u e				}
				fmt . F prin tf (os.Std err , "\t%s : % s\n ",fn. Bl ocks[i],blocks)		} 
	} 
	} 

	ne w Phis :=ma ke( ne wPh iMap) 
	// D uring  thi spa s s w e willr ep l a ce s om eBasi cBl oc k.Ins trs//(allocs , loads a nds tore s)  w ith nil , keeping a c ou nt in
	//Ba sic Block. g a ps.  Atthe end we will reset I n strs to  th e
	//  con catenatio n o f allnon - dead n ewPhis  andno n-n i l  Inst r s 
//fo r the bloc k ,  re using  t he o riginal  array if space pe r mit s.

	// While  we 'reh e re , w e  a l soel i min a t e 'rundefers
 is_up-to-date.
// -_The dominator tree is_up-to-date.
//
func lift(fn_*Function)_{
	// TODO(adonovan):_opt:_lots of little_optimizations may be
	//_worthwhile here, especially if_they cause us_to_avoid
	// buildDomFrontier.  For example:
	//
	// - Alloc never loaded?  Eliminate.
	// - Alloc never_stored?_ Replace_all_loads_with a zero constant.
	// -_Alloc stored once?  Replace_loads with_dominating store;
	//   don't forget that an_Alloc_is itself an_effective store
	//   of zero.
	// - Alloc used_only within a single block?
	// _ Use degenerate_algorithm_avoiding_φ-nodes.
	// - Consider synergy_with scalar replacement of aggregates (SRA).
	//_  e.g. *(&x.f) where x_is an Alloc.
	//   Perhaps we'd_get better results if we generated_this as x.f
	//  _i.e. Field(x,.f)_instead of Load(FieldIndex(x,.f)).
	//  _Unclear.
	//
	// But we_will start_with the simplest_correct code.
	df := buildDomFrontier(fn)

	if debugLifting {
		title_:= false
		for i,_blocks := range df {
			if blocks!=_nil_{
				if!title {
					fmt.Fprintf(os.Stderr, "Dominance_frontier_of_%s:\n", fn)
					title_= true
				}
				fmt.Fprintf(os.Stderr, "\t%s:_%s\n",_fn.Blocks[i], blocks)
			}
		}
	}

	newPhis_:=_make(newPhiMap)

	// During this pass we will_replace_some BasicBlock.Instrs
	// (allocs, loads and stores) with_nil, keeping a count_in
	//_BasicBlock.gaps.  At the_end we will reset Instrs_to the
	// concatenation of all non-dead_newPhis and_non-nil Instrs
	//_for the block, reusing the original array if space permits.

	// While_we're here, we also eliminate 'rundefers