diff options
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r-- | gcc/ada/exp_ch4.adb | 155 |
1 files changed, 82 insertions, 73 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 6a65e10a167..b72b8108f2d 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -8042,88 +8042,54 @@ package body Exp_Ch4 is -- have to be sure not to generate junk overflow checks in the first -- place, since it would be trick to remove them here! - declare - Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type); - - begin - -- Enable transformation if all conditions are met + if Integer_Promotion_Possible (N) then - if - -- We only do this transformation for source constructs. We assume - -- that the expander knows what it is doing when it generates code. - - Comes_From_Source (N) + -- All conditions met, go ahead with transformation - -- If the operand type is Short_Integer or Short_Short_Integer, - -- then we will promote to Integer, which is available on all - -- targets, and is sufficient to ensure no intermediate overflow. - -- Furthermore it is likely to be as efficient or more efficient - -- than using the smaller type for the computation so we do this - -- unconditionally. - - and then - (Root_Operand_Type = Base_Type (Standard_Short_Integer) - or else - Root_Operand_Type = Base_Type (Standard_Short_Short_Integer)) - - -- Test for interesting operation, which includes addition, - -- division, exponentiation, multiplication, subtraction, and - -- unary negation. + declare + Opnd : Node_Id; + L, R : Node_Id; - and then Nkind_In (Operand, N_Op_Add, - N_Op_Divide, - N_Op_Expon, - N_Op_Minus, - N_Op_Multiply, - N_Op_Subtract) - then - -- All conditions met, go ahead with transformation + begin + R := + Make_Type_Conversion (Loc, + Subtype_Mark => New_Reference_To (Standard_Integer, Loc), + Expression => Relocate_Node (Right_Opnd (Operand))); - declare - Opnd : Node_Id; - L, R : Node_Id; + if Nkind (Operand) = N_Op_Minus then + Opnd := Make_Op_Minus (Loc, Right_Opnd => R); - begin - R := + else + L := Make_Type_Conversion (Loc, Subtype_Mark => New_Reference_To (Standard_Integer, Loc), - Expression => Relocate_Node (Right_Opnd (Operand))); - - if Nkind (Operand) = N_Op_Minus then - Opnd := Make_Op_Minus (Loc, Right_Opnd => R); - - else - L := - Make_Type_Conversion (Loc, - Subtype_Mark => New_Reference_To (Standard_Integer, Loc), - Expression => Relocate_Node (Left_Opnd (Operand))); - - case Nkind (Operand) is - when N_Op_Add => - Opnd := Make_Op_Add (Loc, L, R); - when N_Op_Divide => - Opnd := Make_Op_Divide (Loc, L, R); - when N_Op_Expon => - Opnd := Make_Op_Expon (Loc, L, R); - when N_Op_Multiply => - Opnd := Make_Op_Multiply (Loc, L, R); - when N_Op_Subtract => - Opnd := Make_Op_Subtract (Loc, L, R); - when others => - raise Program_Error; - end case; + Expression => Relocate_Node (Left_Opnd (Operand))); + + case Nkind (Operand) is + when N_Op_Add => + Opnd := Make_Op_Add (Loc, L, R); + when N_Op_Divide => + Opnd := Make_Op_Divide (Loc, L, R); + when N_Op_Expon => + Opnd := Make_Op_Expon (Loc, L, R); + when N_Op_Multiply => + Opnd := Make_Op_Multiply (Loc, L, R); + when N_Op_Subtract => + Opnd := Make_Op_Subtract (Loc, L, R); + when others => + raise Program_Error; + end case; - Rewrite (N, - Make_Type_Conversion (Loc, - Subtype_Mark => Relocate_Node (Subtype_Mark (N)), - Expression => Opnd)); + Rewrite (N, + Make_Type_Conversion (Loc, + Subtype_Mark => Relocate_Node (Subtype_Mark (N)), + Expression => Opnd)); - Analyze_And_Resolve (N, Target_Type); - return; - end if; - end; - end if; - end; + Analyze_And_Resolve (N, Target_Type); + return; + end if; + end; + end if; -- Do validity check if validity checking operands @@ -9187,6 +9153,49 @@ package body Exp_Ch4 is return; end Insert_Dereference_Action; + -------------------------------- + -- Integer_Promotion_Possible -- + -------------------------------- + + function Integer_Promotion_Possible (N : Node_Id) return Boolean is + Operand : constant Node_Id := Expression (N); + Operand_Type : constant Entity_Id := Etype (Operand); + Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type); + + begin + pragma Assert (Nkind (N) = N_Type_Conversion); + + return + + -- We only do the transformation for source constructs. We assume + -- that the expander knows what it is doing when it generates code. + + Comes_From_Source (N) + + -- If the operand type is Short_Integer or Short_Short_Integer, + -- then we will promote to Integer, which is available on all + -- targets, and is sufficient to ensure no intermediate overflow. + -- Furthermore it is likely to be as efficient or more efficient + -- than using the smaller type for the computation so we do this + -- unconditionally. + + and then + (Root_Operand_Type = Base_Type (Standard_Short_Integer) + or else + Root_Operand_Type = Base_Type (Standard_Short_Short_Integer)) + + -- Test for interesting operation, which includes addition, + -- division, exponentiation, multiplication, subtraction, and + -- unary negation. + + and then Nkind_In (Operand, N_Op_Add, + N_Op_Divide, + N_Op_Expon, + N_Op_Minus, + N_Op_Multiply, + N_Op_Subtract); + end Integer_Promotion_Possible; + ------------------------------ -- Make_Array_Comparison_Op -- ------------------------------ |