1353940Sdim//===- Combine.td - Combine rule definitions ---------------*- tablegen -*-===// 2353940Sdim// 3353940Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353940Sdim// See https://llvm.org/LICENSE.txt for license information. 5353940Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353940Sdim// 7353940Sdim//===----------------------------------------------------------------------===// 8353940Sdim// 9353940Sdim// Declare GlobalISel combine rules and provide mechanisms to opt-out. 10353940Sdim// 11353940Sdim//===----------------------------------------------------------------------===// 12353940Sdim 13353940Sdim// Common base class for GICombineRule and GICombineGroup. 14353940Sdimclass GICombine { 15353940Sdim // See GICombineGroup. We only declare it here to make the tablegen pass 16353940Sdim // simpler. 17353940Sdim list<GICombine> Rules = ?; 18353940Sdim} 19353940Sdim 20353940Sdim// A group of combine rules that can be added to a GICombiner or another group. 21353940Sdimclass GICombineGroup<list<GICombine> rules> : GICombine { 22353940Sdim // The rules contained in this group. The rules in a group are flattened into 23353940Sdim // a single list and sorted into whatever order is most efficient. However, 24353940Sdim // they will never be re-ordered such that behaviour differs from the 25353940Sdim // specified order. It is therefore possible to use the order of rules in this 26353940Sdim // list to describe priorities. 27353940Sdim let Rules = rules; 28353940Sdim} 29353940Sdim 30353940Sdim// Declares a combiner helper class 31353940Sdimclass GICombinerHelper<string classname, list<GICombine> rules> 32353940Sdim : GICombineGroup<rules> { 33353940Sdim // The class name to use in the generated output. 34353940Sdim string Classname = classname; 35353940Sdim // The name of a run-time compiler option that will be generated to disable 36353940Sdim // specific rules within this combiner. 37353940Sdim string DisableRuleOption = ?; 38353940Sdim} 39353940Sdimclass GICombineRule<dag defs, dag match, dag apply> : GICombine { 40353940Sdim /// Defines the external interface of the match rule. This includes: 41353940Sdim /// * The names of the root nodes (requires at least one) 42353940Sdim /// See GIDefKind for details. 43353940Sdim dag Defs = defs; 44353940Sdim 45353940Sdim /// Defines the things which must be true for the pattern to match 46353940Sdim /// See GIMatchKind for details. 47353940Sdim dag Match = match; 48353940Sdim 49353940Sdim /// Defines the things which happen after the decision is made to apply a 50353940Sdim /// combine rule. 51353940Sdim /// See GIApplyKind for details. 52353940Sdim dag Apply = apply; 53353940Sdim} 54353940Sdim 55353940Sdim/// The operator at the root of a GICombineRule.Defs dag. 56353940Sdimdef defs; 57353940Sdim 58353940Sdim/// All arguments of the defs operator must be subclasses of GIDefKind or 59353940Sdim/// sub-dags whose operator is GIDefKindWithArgs. 60353940Sdimclass GIDefKind; 61353940Sdimclass GIDefKindWithArgs; 62353940Sdim/// Declare a root node. There must be at least one of these in every combine 63353940Sdim/// rule. 64353940Sdim/// TODO: The plan is to elide `root` definitions and determine it from the DAG 65353940Sdim/// itself with an overide for situations where the usual determination 66353940Sdim/// is incorrect. 67353940Sdimdef root : GIDefKind; 68353940Sdim 69357095Sdim/// Declares data that is passed from the match stage to the apply stage. 70357095Sdimclass GIDefMatchData<string type> : GIDefKind { 71357095Sdim /// A C++ type name indicating the storage type. 72357095Sdim string Type = type; 73357095Sdim} 74357095Sdim 75357095Sdimdef extending_load_matchdata : GIDefMatchData<"PreferredTuple">; 76357095Sdimdef indexed_load_store_matchdata : GIDefMatchData<"IndexedLoadStoreMatchInfo">; 77357095Sdim 78353940Sdim/// The operator at the root of a GICombineRule.Match dag. 79353940Sdimdef match; 80353940Sdim/// All arguments of the match operator must be either: 81353940Sdim/// * A subclass of GIMatchKind 82353940Sdim/// * A subclass of GIMatchKindWithArgs 83357095Sdim/// * A subclass of Instruction 84353940Sdim/// * A MIR code block (deprecated) 85353940Sdim/// The GIMatchKind and GIMatchKindWithArgs cases are described in more detail 86353940Sdim/// in their definitions below. 87353940Sdim/// For the Instruction case, these are collected into a DAG where operand names 88353940Sdim/// that occur multiple times introduce edges. 89353940Sdimclass GIMatchKind; 90353940Sdimclass GIMatchKindWithArgs; 91353940Sdim 92357095Sdim/// In lieu of having proper macro support. Trivial one-off opcode checks can be 93357095Sdim/// performed with this. 94357095Sdimdef wip_match_opcode : GIMatchKindWithArgs; 95357095Sdim 96353940Sdim/// The operator at the root of a GICombineRule.Apply dag. 97353940Sdimdef apply; 98353940Sdim/// All arguments of the apply operator must be subclasses of GIApplyKind, or 99353940Sdim/// sub-dags whose operator is GIApplyKindWithArgs, or an MIR block 100353940Sdim/// (deprecated). 101353940Sdimclass GIApplyKind; 102353940Sdimclass GIApplyKindWithArgs; 103353940Sdim 104353940Sdimdef copy_prop : GICombineRule< 105353940Sdim (defs root:$d), 106357095Sdim (match (COPY $d, $s):$mi, 107357095Sdim [{ return Helper.matchCombineCopy(*${mi}); }]), 108357095Sdim (apply [{ Helper.applyCombineCopy(*${mi}); }])>; 109353940Sdimdef trivial_combines : GICombineGroup<[copy_prop]>; 110353940Sdim 111357095Sdimdef extending_loads : GICombineRule< 112357095Sdim (defs root:$root, extending_load_matchdata:$matchinfo), 113357095Sdim (match (wip_match_opcode G_LOAD, G_SEXTLOAD, G_ZEXTLOAD):$root, 114357095Sdim [{ return Helper.matchCombineExtendingLoads(*${root}, ${matchinfo}); }]), 115357095Sdim (apply [{ Helper.applyCombineExtendingLoads(*${root}, ${matchinfo}); }])>; 116357095Sdimdef combines_for_extload: GICombineGroup<[extending_loads]>; 117357095Sdim 118357095Sdimdef combine_indexed_load_store : GICombineRule< 119357095Sdim (defs root:$root, indexed_load_store_matchdata:$matchinfo), 120357095Sdim (match (wip_match_opcode G_LOAD, G_SEXTLOAD, G_ZEXTLOAD, G_STORE):$root, 121357095Sdim [{ return Helper.matchCombineIndexedLoadStore(*${root}, ${matchinfo}); }]), 122357095Sdim (apply [{ Helper.applyCombineIndexedLoadStore(*${root}, ${matchinfo}); }])>; 123357095Sdim 124353940Sdim// FIXME: Is there a reason this wasn't in tryCombine? I've left it out of 125353940Sdim// all_combines because it wasn't there. 126353940Sdimdef elide_br_by_inverting_cond : GICombineRule< 127357095Sdim (defs root:$root), 128357095Sdim (match (wip_match_opcode G_BR):$root, 129357095Sdim [{ return Helper.matchElideBrByInvertingCond(*${root}); }]), 130357095Sdim (apply [{ Helper.applyElideBrByInvertingCond(*${root}); }])>; 131353940Sdim 132357095Sdimdef ptr_add_immed_matchdata : GIDefMatchData<"PtrAddChain">; 133357095Sdimdef ptr_add_immed_chain : GICombineRule< 134357095Sdim (defs root:$d, ptr_add_immed_matchdata:$matchinfo), 135357095Sdim (match (wip_match_opcode G_PTR_ADD):$d, 136357095Sdim [{ return Helper.matchPtrAddImmedChain(*${d}, ${matchinfo}); }]), 137357095Sdim (apply [{ Helper.applyPtrAddImmedChain(*${d}, ${matchinfo}); }])>; 138357095Sdim 139357095Sdimdef all_combines : GICombineGroup<[trivial_combines, ptr_add_immed_chain, 140357095Sdim combines_for_extload, combine_indexed_load_store]>; 141