@@ -230,10 +230,18 @@ package body Tree_Walk is
230
230
function Do_Op_Minus (N : Node_Id) return Irep
231
231
with Pre => Nkind (N) in N_Op;
232
232
233
- function Do_Op_Or (N : Node_Id) return Irep
234
- with Pre => Nkind (N) in N_Op;
235
-
236
- function Do_Op_And (N : Node_Id) return Irep
233
+ type Bit_Operand_Constructor is
234
+ access function (Lhs : Irep;
235
+ Rhs : Irep;
236
+ Source_Location : Source_Ptr;
237
+ Overflow_Check : Boolean;
238
+ I_Type : Irep;
239
+ Range_Check : Boolean)
240
+ return Irep;
241
+
242
+ function Do_Bit_Op (N : Node_Id;
243
+ Operator : Bit_Operand_Constructor)
244
+ return Irep
237
245
with Pre => Nkind (N) in N_Op;
238
246
239
247
procedure Do_Package_Declaration (N : Node_Id)
@@ -3531,36 +3539,26 @@ package body Tree_Walk is
3531
3539
end Do_Op_Minus ;
3532
3540
3533
3541
-- -----------------------
3534
- -- Do_Op_Or --
3535
- -- -----------------------
3536
-
3537
- function Do_Op_Or (N : Node_Id) return Irep is
3538
- LHS_Bool_Value : constant Irep := Do_Expression (Left_Opnd (N));
3539
- RHS_Bool_Value : constant Irep := Do_Expression (Right_Opnd (N));
3540
- Cast_LHS_To_Integer : constant Irep :=
3541
- Make_Op_Typecast (Op0 => LHS_Bool_Value,
3542
- Source_Location => Sloc (N),
3543
- I_Type => Make_Signedbv_Type (Make_Nil_Type, 32 ));
3544
- Cast_RHS_To_Integer : constant Irep :=
3545
- Make_Op_Typecast (Op0 => RHS_Bool_Value,
3546
- Source_Location => Sloc (N),
3547
- I_Type => Make_Signedbv_Type (Make_Nil_Type, 32 ));
3548
- R : constant Irep := Make_Op_Bitor (Lhs => Cast_LHS_To_Integer,
3549
- Rhs => Cast_RHS_To_Integer,
3550
- Source_Location => Sloc (N),
3551
- I_Type =>
3552
- Get_Type (Cast_LHS_To_Integer));
3553
- begin
3554
- return Make_Op_Typecast (Op0 => R,
3555
- Source_Location => Sloc (N),
3556
- I_Type => Make_Bool_Type);
3557
- end Do_Op_Or ;
3558
-
3559
- -- -----------------------
3560
- -- Do_Op_And --
3542
+ -- Do_Bit_Op --
3561
3543
-- -----------------------
3562
3544
3563
- function Do_Op_And (N : Node_Id) return Irep is
3545
+ -- We identified that the constructor for operator `or` and operator
3546
+ -- `and` were pretty much the same, with the only difference being
3547
+ -- the constructor being called. So to avoid needless duplication,
3548
+ -- we simplified it to a single function that does the same thing,
3549
+ -- and just calls the appropriate constructor via a function pointer.
3550
+ --
3551
+ -- This produces the following code in pseudocode (let A and B be True):
3552
+ -- A or B
3553
+ -- --
3554
+ -- int intA = (int) A; // 1
3555
+ -- int intB = (int) B; // 1
3556
+ -- int intC = A bitop B // bitop can be `or` or `and`
3557
+ -- int R = (boolean) intC;
3558
+ -- return R;
3559
+ function Do_Bit_Op (N : Node_Id;
3560
+ Operator : Bit_Operand_Constructor)
3561
+ return Irep is
3564
3562
LHS_Bool_Value : constant Irep := Do_Expression (Left_Opnd (N));
3565
3563
RHS_Bool_Value : constant Irep := Do_Expression (Right_Opnd (N));
3566
3564
Cast_LHS_To_Integer : constant Irep :=
@@ -3571,16 +3569,18 @@ package body Tree_Walk is
3571
3569
Make_Op_Typecast (Op0 => RHS_Bool_Value,
3572
3570
Source_Location => Sloc (N),
3573
3571
I_Type => Make_Signedbv_Type (Make_Nil_Type, 32 ));
3574
- R : constant Irep := Make_Op_Bitand (Rhs => Cast_RHS_To_Integer,
3575
- Lhs => Cast_LHS_To_Integer,
3576
- Source_Location => Sloc (N),
3577
- I_Type =>
3578
- Get_Type (Cast_LHS_To_Integer));
3572
+ R : constant Irep := Operator (Lhs => Cast_LHS_To_Integer,
3573
+ Rhs => Cast_RHS_To_Integer,
3574
+ Source_Location => Sloc (N),
3575
+ Overflow_Check => False,
3576
+ Range_Check => False,
3577
+ I_Type =>
3578
+ Get_Type (Cast_LHS_To_Integer));
3579
3579
begin
3580
3580
return Make_Op_Typecast (Op0 => R,
3581
3581
Source_Location => Sloc (N),
3582
3582
I_Type => Make_Bool_Type);
3583
- end Do_Op_And ;
3583
+ end Do_Bit_Op ;
3584
3584
3585
3585
-- -----------------------
3586
3586
-- Do_Operator_General --
@@ -3596,9 +3596,9 @@ package body Tree_Walk is
3596
3596
elsif Nkind (N) = N_Op_Minus then
3597
3597
return Do_Op_Minus (N);
3598
3598
elsif Nkind (N) = N_Op_Or then
3599
- return Do_Op_Or (N);
3599
+ return Do_Bit_Op (N, Make_Op_Bitor' Access );
3600
3600
elsif Nkind (N) = N_Op_And then
3601
- return Do_Op_And (N);
3601
+ return Do_Bit_Op (N, Make_Op_Bitand' Access );
3602
3602
else
3603
3603
if Nkind (N) /= N_And_Then
3604
3604
and then Nkind (N) /= N_In
0 commit comments