private void FuseStorePair(Tuple <UnalignedAccess, UnalignedAccess> pair) { Statement stmL, stmR; if (pair.Item1.isLeft) { stmL = pair.Item1.stm !; stmR = pair.Item2.stm !; } else { stmL = pair.Item2.stm !; stmR = pair.Item1.stm !; } ssa.RemoveUses(stmL); ssa.RemoveUses(stmR); if (pair.Item1.mem is Identifier id) { stmR.Instruction = new Assignment(id, pair.Item1.value !); } else { var memId = ((MemoryAccess)((Store)pair.Item2.stm !.Instruction).Dst).MemoryId; var sidMem = ssa.Identifiers[memId]; sidMem.DefStatement = null; stmR.Instruction = new Store( pair.Item1.mem !, pair.Item1.value !); } stmL.Block.Statements.Remove(stmL); ssa.AddUses(stmR); }
public void AdjustSsa(Statement stm, CallInstruction call) { ssa.ReplaceDefinitions(stm, null); ssa.RemoveUses(stm); ssa.AddDefinitions(stm); ssa.AddUses(stm); DefineUninitializedIdentifiers(stm, call); }
private void RemoveImplicitRegistersFromHellNode( SsaState ssa, Statement stm) { if (!(stm.Instruction is CallInstruction ci)) { return; } if (ci.Callee is ProcedureConstant pc) { if (!(pc.Procedure is ExternalProcedure)) { return; } } var trashedRegisters = program.Platform.CreateTrashedRegisters(); var implicitRegs = program.Platform.CreateImplicitArgumentRegisters(); foreach (var use in ci.Uses.ToList()) { if (IsPreservedRegister(trashedRegisters, use.Storage) || IsStackStorageOfPreservedRegister( ssa, trashedRegisters, use) || implicitRegs.Contains(use.Storage)) { ci.Uses.Remove(use); ssa.RemoveUses(stm, use.Expression); } } }
public void Transform(Statement stm, CallInstruction call) { this.stm = stm; this.call = call; ssa.ReplaceDefinitions(stm, null); ssa.RemoveUses(stm); Transform(stm.Instruction); }
private Expression RewriteSeqOfPhi(SsaIdentifier[] sids, PhiAssignment[] phis, Identifier idWide) { // We have // a_3 = PHI(a_1, a_2) // b_3 = PHI(b_1, a_2) // ...SEQ(a_3,b_3) // and we want // ab_3 = PHI(ab_1, ab_2) // a_3 = SLICE(ab_3, ...) // b_3 = SLICE(ab_3, ...) // ...ab_3 foreach (var s in sids) { s.Uses.Remove(this.Statement); } // Insert a PHI statement placeholder at the beginning // of the basic block. var stmPhi = sids[0].DefStatement.Block.Statements.Insert( 0, sids[0].DefStatement.LinearAddress, null); // Generate fused identifiers for all phi slots. var widePhiArgs = new List <PhiArgument>(); for (var iBlock = 0; iBlock < phis[0].Src.Arguments.Length; ++iBlock) { // Make a fused identifier in each predecessor block and "push" // the SEQ statements into the predecessors. var pred = phis[0].Src.Arguments[iBlock].Block; var sidPred = MakeFusedIdentifierInPredecessorBlock(sids, phis, idWide, stmPhi, iBlock, pred); widePhiArgs.Add(new PhiArgument(pred, sidPred.Identifier)); } var sidDst = ssa.Identifiers.Add(idWide, stmPhi, null, false); stmPhi.Instruction = new PhiAssignment( sidDst.Identifier, widePhiArgs.ToArray()); sidDst.Uses.Add(this.Statement); // Replace all the "unfused" phis with slices of the "fused" phi. foreach (var sid in sids) { ssa.RemoveUses(sid.DefStatement); sid.DefStatement.Instruction = new AliasAssignment( sid.Identifier, new Slice(sid.Identifier.DataType, sidDst.Identifier, idWide.Storage.OffsetOf(sid.Identifier.Storage))); sidDst.Uses.Add(sid.DefStatement); } return(sidDst.Identifier); }
public void RewriteCall(Statement stm, CallInstruction call, FunctionType ft) { ssam.AdjustRegisterAfterCall( stm, call, ssa.Procedure.Architecture.StackRegister, ft.StackDelta - call.CallSite.SizeOfReturnAddressOnStack); ssam.AdjustRegisterAfterCall( stm, call, program.Architecture.FpuStackRegister, -ft.FpuStackDelta); var ab = program.Architecture.CreateFrameApplicationBuilder( proc.Frame, call.CallSite, call.Callee); ssa.RemoveUses(stm); stm.Instruction = ab.CreateInstruction(ft, null); ssaIdTransformer.Transform(stm, call); ssam.DefineUninitializedIdentifiers(stm, call); }
// On MIPS-LE the sequence // lwl rx,K+3(ry) // lwr rx,K(ry) // is an unaligned read. On MIPS-BE it instead is: // lwl rx,K(ry) // lwr rx,K+3(ry) public void FuseUnalignedLoads(Assignment assR) { var appR = MatchIntrinsicApplication(assR.Src, unalignedLoadsLe); if (appR == null) { return; } var regR = assR.Dst; var stmR = ssa.Identifiers[regR].DefStatement; var memR = appR.Item2.Arguments[1]; var offR = GetOffsetOf(memR); var appL = appR.Item2.Arguments[0] as Application; Statement stmL = null; Assignment assL = null; if (appL == null) { var regL = (Identifier)appR.Item2.Arguments[0]; stmL = ssa.Identifiers[regL].DefStatement; if (stmL == null) { return; } assL = stmL.Instruction as Assignment; if (assL == null) { return; } appL = assL.Src as Application; } var pairL = MatchIntrinsicApplication(appL, unalignedLoadsBe); if (pairL == null) { return; } var applL = pairL.Item2; var memL = appL.Arguments[1]; var offL = GetOffsetOf(memL); Expression mem; if (offR + 3 == offL) { // Little endian use mem = memR; } else if (offL + 3 == offR) { // Big endian use mem = memL; } else { return; } ssa.RemoveUses(stmL); ssa.RemoveUses(stmR); if (assL != null) { assL.Src = appL.Arguments[0]; ssa.AddUses(stmL); } assR.Src = mem; if (stmL != null) { stmL.Block.Statements.Remove(stmL); } ssa.AddUses(stmR); }
private Instruction TransformRolC(Application rolc, Assignment a) { var sidOrigHi = ssaIds[a.Dst]; var sidCarry = ssaIds[(Identifier)rolc.Arguments[2]]; var cond = sidCarry.DefExpression as ConditionOf; if (cond == null) { return(a); } var condId = cond.Expression as Identifier; if (condId == null) { return(a); } var sidOrigLo = ssaIds[condId]; var shift = sidOrigLo.DefExpression as BinaryExpression; if (shift == null || shift.Operator != Operator.Shl) { return(a); } var block = sidOrigHi.DefStatement.Block; var sidShift = sidOrigLo.DefStatement; var expShrSrc = shift.Left; var expRorSrc = rolc.Arguments[0]; var stmGrf = sidGrf.DefStatement; block.Statements.Remove(stmGrf); // xx = lo var tmpLo = ssa.Procedure.Frame.CreateTemporary(expShrSrc.DataType); var sidTmpLo = ssaIds.Add(tmpLo, sidOrigLo.DefStatement, expShrSrc, false); sidOrigLo.DefStatement.Instruction = new Assignment(sidTmpLo.Identifier, expShrSrc); var tmpHi = ssa.Procedure.Frame.CreateTemporary(rolc.Arguments[0].DataType); var sidTmpHi = ssaIds.Add(tmpHi, sidOrigHi.DefStatement, rolc.Arguments[0], false); sidOrigHi.DefStatement.Instruction = new Assignment(sidTmpHi.Identifier, rolc.Arguments[0]); var iRolc = block.Statements.IndexOf(sidOrigHi.DefStatement); var dt = PrimitiveType.Create(Domain.Integer, expShrSrc.DataType.Size + expRorSrc.DataType.Size); var tmp = ssa.Procedure.Frame.CreateTemporary(dt); var expMkLongword = m.Shl(m.Seq(sidTmpHi.Identifier, sidTmpLo.Identifier), 1); var sidTmp = ssaIds.Add(tmp, sidGrf.DefStatement, expMkLongword, false); var stmTmp = block.Statements.Insert(iRolc + 1, sidOrigHi.DefStatement.LinearAddress, new Assignment(sidTmp.Identifier, expMkLongword)); sidTmp.DefStatement = stmTmp; sidTmpLo.Uses.Add(stmTmp); sidTmpHi.Uses.Add(stmTmp); ssa.RemoveUses(sidCarry.DefStatement); block.Statements.Remove(sidCarry.DefStatement); ssaIds.Remove(sidCarry); var expNewLo = m.Cast( PrimitiveType.CreateWord(tmpHi.DataType.Size), sidTmp.Identifier); var stmNewLo = block.Statements.Insert( iRolc + 2, sidOrigLo.DefStatement.LinearAddress, new Assignment(sidOrigLo.Identifier, expNewLo)); sidTmp.Uses.Add(stmNewLo); sidOrigLo.DefStatement = stmNewLo; sidOrigLo.DefExpression = expNewLo; var expNewHi = m.Slice( PrimitiveType.CreateWord(tmpLo.DataType.Size), sidTmp.Identifier, (uint)tmpHi.DataType.BitSize); var stmNewHi = block.Statements.Insert( iRolc + 3, sidOrigHi.DefStatement.LinearAddress, new Assignment(sidOrigHi.Identifier, expNewHi)); sidTmp.Uses.Add(stmNewHi); sidOrigHi.DefStatement = stmNewHi; sidOrigHi.DefStatement = stmNewHi; sidGrf.DefExpression = m.Cond(sidTmp.Identifier); sidGrf.DefStatement.Instruction = new Assignment( sidGrf.Identifier, sidGrf.DefExpression); sidTmp.Uses.Add(sidGrf.DefStatement); return(sidOrigHi.DefStatement.Instruction); }