Переглянути джерело

Start documenting optimizer passes

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 роки тому
батько
коміт
a90610ead0
2 змінених файлів з 54 додано та 0 видалено
  1. 1 0
      docs/index.rst
  2. 53 0
      docs/optimizer.rst

+ 1 - 0
docs/index.rst

@@ -31,6 +31,7 @@ and we have a `channel on chat.hyperledger.org <https://chat.hyperledger.org/cha
    status
    running
    language
+   optimizer
    extension
    examples
    contributing

+ 53 - 0
docs/optimizer.rst

@@ -0,0 +1,53 @@
+Optimizer Passes
+================
+
+Solang generates its own internal IR, before the LLVM IR is generated. This internal IR allows us to do
+several optimizations which LLVM cannot do, since it is not aware of higher-level language constructs.
+
+Arithmetic of large integers (larger than 64 bit) has special handling, since LLVM cannot generate them.
+So we need to do our own optimizations for these types, and we cannot rely on LLVM.
+
+Constant Folding Pass
+---------------------
+
+There is a constant folding (also called constant propagation) pass done, before all the other passes. This
+helps arithmetic of large types, and also means that the functions are constant folded when their arguments
+are constant. For example:
+
+
+.. code-block:: javascript
+
+    bytes32 hash = keccak256('foobar');
+
+This is evaluated at compile time. You can see this in the Visual Studio Code extension by hover over `hash`;
+the hover will tell you the value of the hash.
+
+Strength Reduction Pass
+-----------------------
+
+Strength reduction is when expensive arithmetic is replaced with cheaper ones. So far, the following types
+of arithmetic may be replaced:
+
+- 256 or 128 bit multiply maybe replaced by 64 bit multiply or shift
+- 256 or 128 bit divide maybe replaced by 64 bit divide or shift
+- 256 or 128 bit modulo maybe replaced by 64 bit modulo or bitwise and
+
+.. code-block:: javascript
+
+    contract test {
+        function f() public {
+            for (uint i = 0; i < 10; i++) {
+                // this multiply can be done with a 64 bit instruction
+                g(i * 100));
+            }
+        }
+
+        function g(uint256 v) internal {
+            // ...
+        }
+    }
+
+Solang uses reaching definitions to track the known bits of the variables; here solang knows that i can have
+the values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and the other operand is always 100. So, the multiplication can be
+done using a single 64 bit multiply instruction. If you hover over the ``*`` in the Visual Studio Code you
+will see this noted.