From 427ebeab6726799bb93f7720f48aea27a7a2e964 Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Mon, 19 Jun 2023 16:27:31 -0300 Subject: [PATCH] Avoid repeated global strings Signed-off-by: Lucas Steuernagel --- src/emit/binary.rs | 16 +- .../solidity/global_strings.sol | 153 ++++++++++++++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 tests/codegen_testcases/solidity/global_strings.sol diff --git a/src/emit/binary.rs b/src/emit/binary.rs index a6fc429313..991d10e39d 100644 --- a/src/emit/binary.rs +++ b/src/emit/binary.rs @@ -59,6 +59,7 @@ pub struct Binary<'a> { pub(crate) return_values: HashMap>, /// No initializer for vector_new pub(crate) vector_init_empty: PointerValue<'a>, + global_strings: RefCell, PointerValue<'a>>>, } impl<'a> Binary<'a> { @@ -322,6 +323,7 @@ impl<'a> Binary<'a> { .i8_type() .ptr_type(AddressSpace::default()) .const_null(), + global_strings: RefCell::new(HashMap::new()), } } @@ -359,6 +361,11 @@ impl<'a> Binary<'a> { data: &[u8], constant: bool, ) -> PointerValue<'a> { + if let Some(emitted_string) = self.global_strings.borrow().get(data) { + if constant { + return *emitted_string; + } + } let ty = self.context.i8_type().array_type(data.len() as u32); let gv = self @@ -372,9 +379,14 @@ impl<'a> Binary<'a> { if constant { gv.set_constant(true); gv.set_unnamed_addr(true); + let ptr_val = gv.as_pointer_value(); + self.global_strings + .borrow_mut() + .insert(data.to_vec(), ptr_val); + ptr_val + } else { + gv.as_pointer_value() } - - gv.as_pointer_value() } /// Wrapper for alloca. Ensures that the alloca is done on the first basic block. diff --git a/tests/codegen_testcases/solidity/global_strings.sol b/tests/codegen_testcases/solidity/global_strings.sol new file mode 100644 index 0000000000..7a4d4c248f --- /dev/null +++ b/tests/codegen_testcases/solidity/global_strings.sol @@ -0,0 +1,153 @@ +// RUN: --target solana --emit llvm-ir +// READ: c.ll + + +// BEGIN-CHECK: "math overflow,\0A" +// NOT-CHECK: "math overflow,\0A" + +import "solana"; +contract ServiceRegistrySolana { + struct Service { + address serviceOwner; + uint64 securityDeposit; + address multisig; + bytes32 configHash; + uint32 threshold; + uint32 maxNumAgentInstances; + uint32 numAgentInstances; + uint8 state; + uint32[] agentIds; + uint32[] slots; + uint64[] bonds; + address[] operators; + address[] agentInstances; + uint32[] agentIdForAgentInstances; + } + + address public owner; + address public escrow; + string public baseURI; + uint32 public totalSupply; + string public constant CID_PREFIX = "f01701220"; + uint64 public slashedFunds; + address public drainer; + string public constant VERSION = "1.0.0"; + mapping(bytes32 => uint64) public mapOperatorAndServiceIdOperatorBalances; + mapping (address => address) public mapAgentInstanceOperators; + mapping (address => bool) public mapMultisigs; + Service public services; + + + + constructor(address a, string memory _baseURI) + { + + } + + function changeOwner(address newOwner) external { + + } + + function changeDrainer(address newDrainer) external { + + } + + function transfer(uint32 serviceId, address newServiceOwner) public { + + } + + function create( + address serviceOwner, + bytes32 configHash, + uint32[] memory agentIds, + uint32[] memory slots, + uint64[] memory bonds, + uint32 threshold + ) external returns (uint32 serviceId) + { + + } + + function update( + bytes32 configHash, + uint32[] memory agentIds, + uint32[] memory slots, + uint64[] memory bonds, + uint32 threshold, + uint32 serviceId + ) external returns (bool success) + { + } + + function activateRegistration(uint32 serviceId) external payable returns (bool success) + { + + } + + function registerAgents( + address operator, + uint32 serviceId, + address[] memory agentInstances, + uint32[] agentIds + ) external payable returns (bool success) + { + + } + + function deploy( + uint32 serviceId, + address multisigImplementation, + bytes memory data + ) external returns (address multisig) + { + + } + + function slash(address[] memory agentInstances, uint64[] memory amounts, uint32 serviceId) external + returns (bool success) + { + + } + + function terminate(uint32 serviceId) external returns (bool success, uint64 refund) + { + } + + function unbond(address operator, uint32 serviceId) external returns (bool success, uint64 refund) { + + } + + function getService(uint32 serviceId) external view returns (Service memory service) { + + } + + function getAgentParams(uint32 serviceId) external view + returns (uint32 numAgentIds, uint32[] memory slots, uint64[] memory bonds) + { + + } + + function getAgentInstances(uint32 serviceId) external view + returns (uint32 numAgentInstances, address[] memory agentInstances) + { + + } + + function getOperatorBalance(address operator, uint32 serviceId) external view returns (uint64 balance) + { + } + + function changeMultisigPermission(address multisig, bool permission) external returns (bool success) { + + } + + function drain() external returns (uint64 amount) { + + } + + function ownerOf(uint32 id) public view returns (address addr) { + + } + + function exists() public view {} +}