|
|
@@ -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.
|