// This is before the expression is processed, so ILValue's and constants havn't been assigned public bool SimplifyTernaryOperator(IList <ILNode> body, ILBasicBlock head, int pos) { Debug.Assert(body.Contains(head)); // Debug.Assert((head.Body[0] as ILLabel).Name != "Block_54"); // Debug.Assert((head.Body[0] as ILLabel).Name != "L1257"); ILExpression condExpr; ILLabel trueLabel; ILLabel falseLabel; ILExpression trueExpr; ILLabel trueFall; ILExpression falseExpr; ILLabel falseFall; ILLabel finalFalseFall; ILLabel finalTrueFall; if (head.MatchLastAndBr(GMCode.Bt, out trueLabel, out condExpr, out falseLabel) && labelGlobalRefCount[trueLabel] == 1 && labelGlobalRefCount[falseLabel] == 1 && labelToBasicBlock[trueLabel].MatchSingleAndBr(GMCode.Push, out trueExpr, out trueFall) && labelToBasicBlock[falseLabel].MatchSingleAndBr(GMCode.Push, out falseExpr, out falseFall) && trueFall == falseFall && body.Contains(labelToBasicBlock[trueFall]) // finalFall.Code == GMCode.Pop ) // (finalFall == null || finalFall.Code == GMCode.Pop) { ILBasicBlock trueBlock = labelToBasicBlock[trueLabel]; ILBasicBlock falseBlock = labelToBasicBlock[falseLabel]; ILBasicBlock fallBlock = labelToBasicBlock[trueFall]; ILExpression newExpr = ResolveTernaryExpression(condExpr, trueExpr, falseExpr); head.Body.RemoveTail(GMCode.Bt, GMCode.B); body.RemoveOrThrow(trueBlock); body.RemoveOrThrow(falseBlock); IList <ILExpression> finalFall; // figure out if its a wierd short or not if (fallBlock.MatchSingleAndBr(GMCode.Bt, out finalTrueFall, out finalFall, out finalFalseFall) && finalFall.Count == 0) { head.Body.Add(new ILExpression(GMCode.Bt, finalTrueFall, newExpr)); if (labelGlobalRefCount[trueFall] == 2) { body.RemoveOrThrow(fallBlock); } } else if (fallBlock.Body.Count == 2) // wierd break, { finalFalseFall = fallBlock.GotoLabel(); head.Body.Add(new ILExpression(GMCode.Push, null, newExpr)); // we want to push it for next pass if (labelGlobalRefCount[trueFall] == 2) { body.RemoveOrThrow(fallBlock); } } else if (fallBlock.MatchAt(1, GMCode.Pop)) // generated? wierd instance? { finalFalseFall = fallBlock.EntryLabel(); error.Info("Wierd Generated Pop here", newExpr); head.Body.Add(new ILExpression(GMCode.Push, null, newExpr)); // It should be combined in JoinBasicBlocks function // so don't remove failblock } else if (fallBlock.MatchAt(1, GMCode.Assign, out finalFall)) // This is an assignment case and unsure what its for { finalFall.Add(newExpr); finalFalseFall = fallBlock.EntryLabel(); } if (finalFalseFall == null && fallBlock.MatchLastAt(1, GMCode.Ret)) { head.Body.Add(new ILExpression(GMCode.Ret, null)); } else { Debug.Assert(finalFalseFall != null); head.Body.Add(new ILExpression(GMCode.B, finalFalseFall)); } return(true); } return(false); }