1717#include < mlir/IR/Operation.h>
1818#include < mlir/IR/SymbolTable.h>
1919
20+ #include < patchestry/Passes/Utils.hpp>
21+
2022namespace patchestry ::passes {
2123
2224 bool OperationMatcher::matches (
@@ -133,19 +135,12 @@ namespace patchestry::passes {
133135 }
134136
135137 std::string func_name = func.getName ().str ();
136- std::string func_type = type_to_string (func.getFunctionType ());
137-
138138 for (const auto &context : function_context) {
139139 // Check function name match
140140 if (!matches_pattern (func_name, context.name )) {
141141 continue ;
142142 }
143143
144- // Check function type match if specified
145- if (!context.type .empty () && !matches_pattern (func_type, context.type )) {
146- continue ;
147- }
148-
149144 return true ;
150145 }
151146
@@ -180,7 +175,8 @@ namespace patchestry::passes {
180175
181176 // Check argument type if specified
182177 if (!operand_match.type .empty ()) {
183- if (!matches_type (operand.getType (), operand_match.type )) {
178+ auto variable_type = extract_ssa_value_type (operand);
179+ if (!matches_type (variable_type, operand_match.type )) {
184180 return false ;
185181 }
186182 }
@@ -222,7 +218,7 @@ namespace patchestry::passes {
222218 auto result = results[i];
223219 std::string var_name =
224220 extract_variable_name (op, static_cast < unsigned >(operands.size () + i));
225- std::string var_type = type_to_string (result.getType ());
221+ std::string var_type = utils::convertCIRTypesToCTypes (result.getType ());
226222
227223 for (const auto &var_match : symbol_matches) {
228224 bool name_matches =
@@ -267,7 +263,13 @@ namespace patchestry::passes {
267263
268264 // Check argument type if specified
269265 if (!arg_match.type .empty ()) {
270- if (!matches_type (operand.getType (), arg_match.type )) {
266+ auto variable_type = extract_ssa_value_type (operand);
267+ // Note: The type matching here is relaxed and checks for matching types both
268+ // following the chain of operations or the direct type of the operand; if the
269+ // match is found with any one, it will go ahead with patching.
270+ if (!matches_type (variable_type, arg_match.type )
271+ && !matches_type (operand.getType (), arg_match.type ))
272+ {
271273 return false ;
272274 }
273275 }
@@ -289,7 +291,7 @@ namespace patchestry::passes {
289291 for (unsigned i = 0 ; i < operands.size (); ++i) {
290292 auto operand = operands[i];
291293 std::string var_name = extract_variable_name (op, i);
292- std::string var_type = type_to_string (operand.getType ());
294+ std::string var_type = utils::convertCIRTypesToCTypes (operand.getType ());
293295
294296 for (const auto &var_match : variable_matches) {
295297 bool name_matches =
@@ -356,7 +358,8 @@ namespace patchestry::passes {
356358 return true ;
357359 }
358360
359- std::string type_str = type_to_string (type);
361+ // convert mlir types to c types
362+ std::string type_str = utils::convertCIRTypesToCTypes (type);
360363 return matches_pattern (type_str, type_pattern);
361364 }
362365
@@ -431,6 +434,55 @@ namespace patchestry::passes {
431434 return " " ;
432435 }
433436
437+ mlir::Type OperationMatcher::extract_ssa_value_type (mlir::Value value) {
438+ // Check if the value is defined by an operation that might modify the original type
439+ if (auto defining_op = value.getDefiningOp ()) {
440+ // For cast operations, try to get the original type
441+ if (auto cast_op = mlir::dyn_cast< cir::CastOp >(defining_op)) {
442+ // Follow the cast chain to get the original type
443+ auto src_value = cast_op.getSrc ();
444+ return extract_ssa_value_type (src_value);
445+ }
446+
447+ // For load operations, get the pointed-to type
448+ if (auto load_op = mlir::dyn_cast< cir::LoadOp >(defining_op)) {
449+ auto ptr_value = load_op.getAddr ();
450+ auto ptr_type = ptr_value.getType ();
451+ if (auto cir_ptr_type = mlir::dyn_cast< cir::PointerType >(ptr_type)) {
452+ return cir_ptr_type.getPointee ();
453+ }
454+ }
455+
456+ // For get member operations, try to get the member type
457+ if (auto get_member_op = mlir::dyn_cast< cir::GetMemberOp >(defining_op)) {
458+ // Return the type of the member being accessed
459+ return get_member_op.getType ();
460+ }
461+
462+ // For other operations, recursively check operands
463+ auto operands = defining_op->getOperands ();
464+ if (!operands.empty ()) {
465+ // For simple operations, follow the first operand
466+ return extract_ssa_value_type (operands[0 ]);
467+ }
468+ }
469+
470+ // For block arguments, check if they represent function parameters with original types
471+ if (auto block_arg = mlir::dyn_cast< mlir::BlockArgument >(value)) {
472+ auto block = block_arg.getOwner ();
473+ if (auto parent_op = block->getParentOp ()) {
474+ // For function arguments, the block argument type should be the actual
475+ // parameter type
476+ if (auto func_op = mlir::dyn_cast< cir::FuncOp >(parent_op)) {
477+ return block_arg.getType ();
478+ }
479+ }
480+ }
481+
482+ // Default: return the direct type of the value
483+ return value.getType ();
484+ }
485+
434486 std::string OperationMatcher::extract_symbol_name (mlir::Operation *op) {
435487 // Check for standard symbol attributes
436488 if (auto symbol_name =
0 commit comments