Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid repeated global strings #1377

Merged
merged 1 commit into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/emit/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub struct Binary<'a> {
pub(crate) return_values: HashMap<ReturnCode, IntValue<'a>>,
/// No initializer for vector_new
pub(crate) vector_init_empty: PointerValue<'a>,
global_constant_strings: RefCell<HashMap<Vec<u8>, PointerValue<'a>>>,
}

impl<'a> Binary<'a> {
Expand Down Expand Up @@ -322,6 +323,7 @@ impl<'a> Binary<'a> {
.i8_type()
.ptr_type(AddressSpace::default())
.const_null(),
global_constant_strings: RefCell::new(HashMap::new()),
}
}

Expand Down Expand Up @@ -359,6 +361,11 @@ impl<'a> Binary<'a> {
data: &[u8],
constant: bool,
) -> PointerValue<'a> {
if let Some(emitted_string) = self.global_constant_strings.borrow().get(data) {
if constant {
return *emitted_string;
}
}
let ty = self.context.i8_type().array_type(data.len() as u32);

let gv = self
Expand All @@ -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_constant_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.
Expand Down
153 changes: 153 additions & 0 deletions tests/codegen_testcases/solidity/global_strings.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// RUN: --target solana --emit llvm-ir
// READ: ServiceRegistrySolana.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)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the contract need all those empty functions for this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can shorten the contract, but I left it as it is because it used to generate 1008 definitions of math overflow.
What is your opinion in shortening it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it's not the end of the world. I'll leave that up to you. I just thought that if in the end only 1 single math overflow string instead of 1008 should be generated, the test code could be more to the point.


}

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 {}
}
Loading