Skip to content
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
12 changes: 11 additions & 1 deletion crates/opy-rs/src/compiler/lowering/action_calls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;

use super::super::blizzard_global;
use super::super::size_optimization::{Slot, slot};

fn is_cased_color_tag(text: &[char], index: usize) -> Option<usize> {
let remaining = text[index..].iter().collect::<String>();
Expand Down Expand Up @@ -608,7 +609,16 @@ impl<'a> Lowering<'a> {
// Team.1) but never the argument-only ones (0, the empty string).
let operands =
rule_condition_root && matches!(call_id, "==" | "!=" | "<" | "<=" | ">" | ">=");
for value in args {
for (index, value) in args.iter_mut().enumerate() {
if matches!(self.value(*value), Value::Number(0.0))
&& (matches!(call_id, "==" | "!=" | "<" | "<=" | ">" | ">=")
|| matches!(
slot(call_id, index),
Some(Slot::Boolean | Slot::FalseOnly | Slot::ZeroAsNull)
))
{
continue;
}
*value = self.apply_replacement(*value, call_id, span, operands);
}
}
Expand Down
15 changes: 14 additions & 1 deletion crates/opy-rs/src/compiler/size_optimization.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use workshop_rs::catalog::{Kind, ParamCoercions};
use workshop_rs::{Action, ModifyOp, Value};

use self::literal_slots::{Slot, slot};
pub(super) use self::literal_slots::{Slot, slot};
use super::Compiler;
use super::lowering::{EMPTY_STRING_NAME, Lowering};
use super::operator_optimization::{falsy, literal_text, number_components};
Expand Down Expand Up @@ -94,6 +94,19 @@ impl<'a> SizeOptimizer<'a> {
}

fn modified(&self, op: ModifyOp, value: &mut Value) {
if matches!(op, ModifyOp::Max | ModifyOp::Min) && matches!(value, Value::Number(0.0)) {
let replacement = [
"getCapturePercentage",
"getPayloadProgressPercentage",
"isMatchComplete",
]
.into_iter()
.find(|name| self.replacement(name));
if let Some(name) = replacement {
*value = Value::call(name, []);
return;
}
}
if is_empty_string(value) {
*value = self.empty_string(false);
return;
Expand Down
4 changes: 2 additions & 2 deletions crates/opy-rs/src/compiler/size_optimization/literal_slots.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum Slot {
pub(in crate::compiler) enum Slot {
Boolean,
TrueOnly,
FalseOnly,
ZeroAsNull,
ZeroVectorAsNull,
}

pub(super) fn slot(name: &str, index: usize) -> Option<Slot> {
pub(in crate::compiler) fn slot(name: &str, index: usize) -> Option<Slot> {
Some(match (name, index) {
("startForcingSpawn", 1) => Slot::FalseOnly,
("add", 0 | 1) | ("divide", 0) | ("modulo", 0 | 1) | ("subtract", 1) => Slot::TrueOnly,
Expand Down
5 changes: 5 additions & 0 deletions crates/opy-rs/src/compiler/tests/structural_convergence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ fn size_optimization_action_values_match_the_pinned_oracle() {
assert_converges("structural-size-action-values");
}

#[test]
fn literal_slots_take_precedence_over_the_capture_replacement() {
assert_converges("structural-size-capture-slots");
}

#[test]
fn condition_operands_skip_the_argument_replacements() {
assert_converges("structural-size-condition-replacements");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"schemaVersion": 1,
"id": "synthetic/structural-size-capture-slots",
"category": "compiler",
"features": [
"optimizeForSize",
"preprocessing/replacements"
],
"source": "source.opy",
"tests": {
"source": {
"nativeStatus": "success",
"relationship": "match",
"ruleNames": true
},
"compiler": {
"nativeStatus": "success",
"relationship": "match",
"comparison": "semantic-wir",
"semanticEquivalent": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"compile": {
"diagnostics": [],
"exitCode": 0,
"status": "success",
"stdout": "",
"workshop": "variables {\n global:\n 0: arr\n 1: result\n}\n\nrule (\"capture directive without size optimization\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Index Of Array Value(Global.arr, 0));\n Modify Global Variable(result, Max, 0);\n Modify Global Variable(result, Min, 0);\n Set Global Variable(result, Compare(Global.result, ==, 0));\n Set Global Variable(result, Index Of Array Value(Global.arr, Compare(Global.result, ==, 0)));\n }\n}\n\n//Optimize for size enabled\nrule (\"literal slots precede capture replacement\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Index Of Array Value(Global.arr, Null));\n Set Global Variable(result, Index Of Array Value(Global.arr, 1));\n Set Global Variable(result, Array Contains(Global.arr, Null));\n Set Global Variable(result, Index Of Array Value(Global.arr, Index Of Array Value(Global.arr, Null)));\n Wait(False, Ignore Condition);\n Create HUD Text(All Players(All Teams), Point Capture Percentage, Custom String(\"\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003{0}\", Custom String(\"\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\")), Null, Left, -9999, Color(Orange), Null, Null, Visible To and String, Default Visibility);\n Modify Global Variable(result, Max, Point Capture Percentage);\n Modify Global Variable(result, Min, Point Capture Percentage);\n Set Global Variable(result, Max(Global.arr, False));\n Set Global Variable(result, Min(Global.arr, False));\n Set Global Variable(result, Compare(Global.result, ==, Null));\n Set Global Variable(result, Index Of Array Value(Global.arr, Compare(Global.result, ==, Null)));\n }\n}\n\nrule (\"capture comparison condition\") {\n event {\n Ongoing - Global;\n }\n conditions {\n Global.result == Null;\n }\n actions {\n Set Global Variable(result, 1);\n }\n}\n\n//Optimizations disabled\nrule (\"capture directive with optimizations disabled\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Max(Global.result, 0));\n Set Global Variable(result, Min(Global.result, 0));\n Set Global Variable(result, Compare(Global.result, ==, 0));\n Set Global Variable(result, Index Of Array Value(Global.arr, Compare(Global.result, ==, 0)));\n }\n}\n",
"workshopExact": "variables {\n global:\n 0: arr\n 1: result\n}\n\nrule (\"capture directive without size optimization\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Index Of Array Value(Global.arr, 0));\n Modify Global Variable(result, Max, 0);\n Modify Global Variable(result, Min, 0);\n Set Global Variable(result, Compare(Global.result, ==, 0));\n Set Global Variable(result, Index Of Array Value(Global.arr, Compare(Global.result, ==, 0)));\n }\n}\n\n//Optimize for size enabled\nrule (\"literal slots precede capture replacement\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Index Of Array Value(Global.arr, Null));\n Set Global Variable(result, Index Of Array Value(Global.arr, 1));\n Set Global Variable(result, Array Contains(Global.arr, Null));\n Set Global Variable(result, Index Of Array Value(Global.arr, Index Of Array Value(Global.arr, Null)));\n Wait(False, Ignore Condition);\n Create HUD Text(All Players(All Teams), Point Capture Percentage, Custom String(\"\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003{0}\", Custom String(\"\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\u2003\")), Null, Left, -9999, Color(Orange), Null, Null, Visible To and String, Default Visibility);\n Modify Global Variable(result, Max, Point Capture Percentage);\n Modify Global Variable(result, Min, Point Capture Percentage);\n Set Global Variable(result, Max(Global.arr, False));\n Set Global Variable(result, Min(Global.arr, False));\n Set Global Variable(result, Compare(Global.result, ==, Null));\n Set Global Variable(result, Index Of Array Value(Global.arr, Compare(Global.result, ==, Null)));\n }\n}\n\nrule (\"capture comparison condition\") {\n event {\n Ongoing - Global;\n }\n conditions {\n Global.result == Null;\n }\n actions {\n Set Global Variable(result, 1);\n }\n}\n\n//Optimizations disabled\nrule (\"capture directive with optimizations disabled\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Max(Global.result, 0));\n Set Global Variable(result, Min(Global.result, 0));\n Set Global Variable(result, Compare(Global.result, ==, 0));\n Set Global Variable(result, Index Of Array Value(Global.arr, Compare(Global.result, ==, 0)));\n }\n}\n\n",
"workshopSha256": "e4a7ed467e5831ca205d30cac2d2e2227fd36b8c119fa6cd938338b829eea815"
},
"fixture": "synthetic/structural-size-capture-slots",
"input": {
"files": [
{
"path": "source.opy",
"sha256": "b87390e38852bf1268adb1ba414a988046810705d69ddd8e6b2a62b710d0e1b2"
}
],
"sha256": "3a9dcb53aa184fe9d0ec387e6b32dcd237a638a3acfb75e54ca28020c5ff6659",
"source": "source.opy"
},
"oracle": {
"contentCommit": "5a7d0e294b8cad73b9701987bb584d0551d7fa4d",
"gitHead": "ec763c1d245aa5485ef61af5b2bda4975bce4877",
"integrity": "sha512-C5F6btT5yn19BvHuE0bjMuSd/2esebBabmpL4SYLQFuJ4IdouVOKEoMLLuJFAyNc0Phwrolblj5GDkDGYR0ofg==",
"language": "en-US",
"license": "GPL-3.0-only",
"name": "overpy",
"registryTarball": "https://registry.npmjs.org/overpy/-/overpy-9.7.17.tgz",
"repository": "https://github.com/Zezombye/overpy",
"version": "9.7.17"
},
"schemaVersion": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!replace0ByCapturePercentage
globalvar arr
globalvar result

rule "capture directive without size optimization":
@Event global
result = arr.index(0)
result = max(result, 0)
result = min(result, 0)
result = (result == 0)
result = arr.index(result == 0)

#!optimizeForSize
rule "literal slots precede capture replacement":
@Event global
result = arr.index(0)
result = arr.index(1)
result = 0 in arr
result = arr.index(arr.index(0))
wait(0)
print(0)
result = max(result, 0)
result = min(result, 0)
result = max(arr, 0)
result = min(arr, 0)
result = (result == 0)
result = arr.index(result == 0)

rule "capture comparison condition":
@Event global
@Condition result == 0
result = 1

#!disableOptimizations
rule "capture directive with optimizations disabled":
@Event global
result = max(result, 0)
result = min(result, 0)
result = (result == 0)
result = arr.index(result == 0)
Loading