From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by sourceware.org (Postfix) with ESMTPS id 6F9203858288 for ; Tue, 21 May 2024 07:31:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6F9203858288 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6F9203858288 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::32d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716276676; cv=none; b=nxDg0O99BR0X1qn3YFcCJisFxomDDCamWExZbR5eH5Vb52INc7Bk3K8tYprJ0QgTfm3QIs3cky0vne5eRiUmpyLSHe+XdAd6OIWyyOrOi8oxwqkDKCQYIk+o9L9WS/j1Iy4avLAyBLXuySTRjbGcfnvkbhVGe5hzVfM6TBLW7HA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716276676; c=relaxed/simple; bh=lD9aWBSduKcHlt++7ip4I4xBYz/fY1ZIyEOx/ZUXJAo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=xbuQcwAufHIOYyO7IAArCM3+ACH/OFDfXoqaRumsBSHQaBbpxUFj9e2MfWIEhUFo8uN/GXKGnYNFPXtlT6flQsx5xa0ZReZ3RvJbZ3AuqZEDsoKxZHfVS+GutgnYEBSbZYpRCX0X2w/bezsGVGck6TNPAePqm1qEGf30aMqYfvY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-420180b5838so20672795e9.2 for ; Tue, 21 May 2024 00:31:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1716276671; x=1716881471; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XINQgTgn2II1Ib30Lr7lsMk49xM397g49zogKB6z+ck=; b=iXYVsTmNJMhLPovrBYBRCCI689mgzxQSgqTTIhUq3yIGQqqxBzz5e5TPio7kPzRsSJ 9UX79V/8EDeflUdRzs7oo1rpy+/KjLSs9irpZy8CbkhZUiZBNflXv3GZ7laqxR0ugpYR OhCitSWiBtt24tJZ+6wrbxylBx8anDVLliKCAesoWDsoFurc1/vwSOyq7rXi01UFnylS ZoY/l0PLH7rxhZ9uIePEld9GTOYpxk4EFQwy8mQc9FScMEMp5fuy8Y5nbTquQPzzARTm AWKFxQXMLtEc6YgK+4CZ+Ym33qnE/nnkCpdnykUQdD9jBgG4sv3M2dvR26V4oQY7aDzO iTkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716276671; x=1716881471; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XINQgTgn2II1Ib30Lr7lsMk49xM397g49zogKB6z+ck=; b=jxu5GrvVdMmXf6bLymX3o4RxtwPIovlNLT82t/vr8Q/8KUGvgku5aHbtOFFITqIz/8 AAUZPWkBgW7MV67fKdGD1pCr7IikCfmwssvLdntKOCW1QtIYP4Yyd91Itghv4BUFw0Sj iBrXURd/fVOFWt9ZrjxPu7San0Kq5OYMIA6fUg/Qg1xV3bDqD1K0o1TBsIq+cRz1TGqT uxRYUdEll/7thh4BAZneoGM4Grbst05UQhcM4w7coFQnW2Wv/38jKBhLz5XIGt7eGG0g 4simTcoa7I6JKXYeWnwU01trYEZMCKIOIsTIx/fXMnBYAD93DsOksCWCjR2+jXUSYEmS 9KNA== X-Gm-Message-State: AOJu0YxKkZltf07dzrlgT3iWigrH8aXsYS3KcO6ve9E6wJFwQ9G22jza /6wrBJ91WpGPYETSkGTZTcba3Tv7ZR+sm54xVX5ElFw/Pc2pM306NxXcuvG44mBIy3Q97nE9JDE = X-Google-Smtp-Source: AGHT+IEQsSrcnlKjCXz2QZtan7s5ylSy0NaJFiGVpTZK2dPuwa8CLY/g24Q718fUgAfCw+z3/iscmQ== X-Received: by 2002:a05:600c:4f93:b0:416:7b2c:df0f with SMTP id 5b1f17b1804b1-41fea931f13mr296534585e9.7.1716276671224; Tue, 21 May 2024 00:31:11 -0700 (PDT) Received: from localhost.localdomain ([2001:861:3382:1a90:de37:8b1c:1f33:2610]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-41fccee9292sm453333645e9.37.2024.05.21.00.31.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 May 2024 00:31:10 -0700 (PDT) From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= To: gcc-patches@gcc.gnu.org Cc: Eric Botcazou Subject: [COMMITTED 31/31] ada: Streamline implementation of simple nonbinary modular operations Date: Tue, 21 May 2024 09:30:34 +0200 Message-ID: <20240521073035.314024-31-poulhies@adacore.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240521073035.314024-1-poulhies@adacore.com> References: <20240521073035.314024-1-poulhies@adacore.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Eric Botcazou They are implemented by the nonbinary_modular_operation routine, which is complex and, in particular, creates signed types and types with a partial precision each time a subtraction or a multiplication resp. is generated. Both are unnecessary and a simple approach even generates better code for the subtraction on architectures with conditional moves. gcc/ada/ * gcc-interface/utils2.cc (nonbinary_modular_operation): Rewrite. Do not create signed types for subtraction, do not create types with partial precision, call fold_convert instead of convert throughout. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/gcc-interface/utils2.cc | 91 ++++++++++----------------------- 1 file changed, 28 insertions(+), 63 deletions(-) diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index 8fb86ab29e3..4b7e2739f6a 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -535,85 +535,50 @@ compare_fat_pointers (location_t loc, tree result_type, tree p1, tree p2) } /* Compute the result of applying OP_CODE to LHS and RHS, where both are of - type TYPE. We know that TYPE is a modular type with a nonbinary - modulus. */ + TYPE. We know that TYPE is a modular type with a nonbinary modulus. */ static tree nonbinary_modular_operation (enum tree_code op_code, tree type, tree lhs, tree rhs) { tree modulus = TYPE_MODULUS (type); - unsigned int needed_precision = tree_floor_log2 (modulus) + 1; - unsigned int precision; - bool unsignedp = true; - tree op_type = type; - tree result; + unsigned precision = tree_floor_log2 (modulus) + 1; + tree op_type, result; - /* If this is an addition of a constant, convert it to a subtraction - of a constant since we can do that faster. */ - if (op_code == PLUS_EXPR && TREE_CODE (rhs) == INTEGER_CST) - { - rhs = fold_build2 (MINUS_EXPR, type, modulus, rhs); - op_code = MINUS_EXPR; - } - - /* For the logical operations, we only need PRECISION bits. For - addition and subtraction, we need one more and for multiplication we - need twice as many. But we never want to make a size smaller than - our size. */ + /* For the logical operations, we only need PRECISION bits. For addition and + subtraction, we need one more, and for multiplication twice as many. */ if (op_code == PLUS_EXPR || op_code == MINUS_EXPR) - needed_precision += 1; + precision += 1; else if (op_code == MULT_EXPR) - needed_precision *= 2; - - precision = MAX (needed_precision, TYPE_PRECISION (op_type)); + precision *= 2; - /* Unsigned will do for everything but subtraction. */ - if (op_code == MINUS_EXPR) - unsignedp = false; - - /* If our type is the wrong signedness or isn't wide enough, make a new - type and convert both our operands to it. */ - if (TYPE_PRECISION (op_type) < precision - || TYPE_UNSIGNED (op_type) != unsignedp) + /* If the type is not wide enough, make a new type of the needed precision + and convert modulus and operands to it. Use a type with full precision + for its mode since operations are ultimately performed in the mode. */ + if (TYPE_PRECISION (type) < precision) { - /* Copy the type so we ensure it can be modified to make it modular. */ - op_type = copy_type (gnat_type_for_size (precision, unsignedp)); - modulus = convert (op_type, modulus); - SET_TYPE_MODULUS (op_type, modulus); - TYPE_MODULAR_P (op_type) = 1; - lhs = convert (op_type, lhs); - rhs = convert (op_type, rhs); + const scalar_int_mode m = smallest_int_mode_for_size (precision); + op_type = gnat_type_for_mode (m, 1); + modulus = fold_convert (op_type, modulus); + lhs = fold_convert (op_type, lhs); + rhs = fold_convert (op_type, rhs); } + else + op_type = type; /* Do the operation, then we'll fix it up. */ result = fold_build2 (op_code, op_type, lhs, rhs); - /* For multiplication, we have no choice but to do a full modulus - operation. However, we want to do this in the narrowest - possible size. */ - if (op_code == MULT_EXPR) - { - /* Copy the type so we ensure it can be modified to make it modular. */ - tree div_type = copy_type (gnat_type_for_size (needed_precision, 1)); - modulus = convert (div_type, modulus); - SET_TYPE_MODULUS (div_type, modulus); - TYPE_MODULAR_P (div_type) = 1; - result = convert (op_type, - fold_build2 (TRUNC_MOD_EXPR, div_type, - convert (div_type, result), modulus)); - } + /* Unconditionally add the modulus to the result for a subtraction, this gets + rid of all its peculiarities by cancelling out the addition of the binary + modulus in the case where the subtraction wraps around in OP_TYPE, and may + even generate better code on architectures with conditional moves. */ + if (op_code == MINUS_EXPR) + result = fold_build2 (PLUS_EXPR, op_type, result, modulus); - /* For subtraction, add the modulus back if we are negative. */ - else if (op_code == MINUS_EXPR) - { - result = gnat_protect_expr (result); - result = fold_build3 (COND_EXPR, op_type, - fold_build2 (LT_EXPR, boolean_type_node, result, - build_int_cst (op_type, 0)), - fold_build2 (PLUS_EXPR, op_type, result, modulus), - result); - } + /* For a multiplication, we have no choice but to use a modulo operation. */ + if (op_code == MULT_EXPR) + result = fold_build2 (TRUNC_MOD_EXPR, op_type, result, modulus); /* For the other operations, subtract the modulus if we are >= it. */ else @@ -627,7 +592,7 @@ nonbinary_modular_operation (enum tree_code op_code, tree type, tree lhs, result); } - return convert (type, result); + return fold_convert (type, result); } /* This page contains routines that implement the Ada semantics with regard -- 2.43.2