InlineAsm.cpp revision ea21ad49261a6a9d1614c01e631c2cdc4d554b84
1cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===// 2cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 3cc041ba03aed685400197fb938b7a583713d25afChris Lattner// The LLVM Compiler Infrastructure 4cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 8cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===----------------------------------------------------------------------===// 9cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 10cc041ba03aed685400197fb938b7a583713d25afChris Lattner// This file implements the InlineAsm class. 11cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 12cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===----------------------------------------------------------------------===// 13cc041ba03aed685400197fb938b7a583713d25afChris Lattner 14cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/InlineAsm.h" 15cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/DerivedTypes.h" 1609f0bd39b16eec73e067561c0c7546902ce97c30Jeff Cohen#include <algorithm> 173b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner#include <cctype> 18cc041ba03aed685400197fb938b7a583713d25afChris Lattnerusing namespace llvm; 19cc041ba03aed685400197fb938b7a583713d25afChris Lattner 20afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen// Implement the first virtual method in this class in this file so the 21afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen// InlineAsm vtable is emitted here. 22afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon HenriksenInlineAsm::~InlineAsm() { 23afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen} 24afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 25afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 2680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner// NOTE: when memoizing the function type, we have to be careful to handle the 2780cd11561892a639a2628d19815af0695b5dbcaaChris Lattner// case when the type gets refined. 2880cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 2980cd11561892a639a2628d19815af0695b5dbcaaChris LattnerInlineAsm *InlineAsm::get(const FunctionType *Ty, const std::string &AsmString, 3080cd11561892a639a2628d19815af0695b5dbcaaChris Lattner const std::string &Constraints, bool hasSideEffects) { 3180cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // FIXME: memoize! 3280cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects); 3380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 3480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 35cc041ba03aed685400197fb938b7a583713d25afChris LattnerInlineAsm::InlineAsm(const FunctionType *Ty, const std::string &asmString, 36863517aea0b06770c809396be985c1c4cc50d3c4Chris Lattner const std::string &constraints, bool hasSideEffects) 3743ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb : Value(PointerType::getUnqual(Ty), 3843ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb Value::InlineAsmVal), 3943ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb AsmString(asmString), 40863517aea0b06770c809396be985c1c4cc50d3c4Chris Lattner Constraints(constraints), HasSideEffects(hasSideEffects) { 41cc041ba03aed685400197fb938b7a583713d25afChris Lattner 4280cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // Do various checks on the constraint string and type. 4380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner assert(Verify(Ty, constraints) && "Function type not legal for constraints!"); 44cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 45cc041ba03aed685400197fb938b7a583713d25afChris Lattner 46cc041ba03aed685400197fb938b7a583713d25afChris Lattnerconst FunctionType *InlineAsm::getFunctionType() const { 47cc041ba03aed685400197fb938b7a583713d25afChris Lattner return cast<FunctionType>(getType()->getElementType()); 48cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 4980cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 50a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the 51a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// fields in this structure. If the constraint string is not understood, 52a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// return true, otherwise return false. 532f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattnerbool InlineAsm::ConstraintInfo::Parse(const std::string &Str, 542f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) { 55a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator I = Str.begin(), E = Str.end(); 563b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 57a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Initialize 58a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isInput; 59a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = false; 602f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner hasMatchingInput = false; 61fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = false; 6273d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = false; 63a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 6473d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // Parse prefixes. 65a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '~') { 66a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isClobber; 67a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 68a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else if (*I == '=') { 69a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 70a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isOutput; 7173d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner } 7273d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner 7373d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (*I == '*') { 7473d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = true; 7573d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner ++I; 76a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 77a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 78a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just a prefix, like "==" or "~". 79a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 80a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the modifiers. 81a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner bool DoneWithModifiers = false; 82a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (!DoneWithModifiers) { 83a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (*I) { 84a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner default: 85a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner DoneWithModifiers = true; 86a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 87fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '&': // Early clobber. 88a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (Type != isOutput || // Cannot early clobber anything but output. 89a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber) // Reject &&&&&& 90a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return true; 91a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = true; 92a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 93fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '%': // Commutative. 94fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner if (Type == isClobber || // Cannot commute clobbers. 95fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative) // Reject %%%%% 96fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; 97fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = true; 98fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner break; 99fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '#': // Comment. 100fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '*': // Register preferencing. 101fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; // Not supported. 102a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 103a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 104a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (!DoneWithModifiers) { 1053b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 106a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just prefixes and modifiers! 107a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 108a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 109a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 110a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the various constraints. 111a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E) { 112a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '{') { // Physical register reference. 113a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of the register name. 114a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator ConstraintEnd = std::find(I+1, E, '}'); 115a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == E) return true; // "{foo" 116a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(I, ConstraintEnd+1)); 117a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd+1; 1182f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner } else if (isdigit(*I)) { // Matching Constraint 119a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Maximal munch numbers. 120a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator NumStart = I; 121a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E && isdigit(*I)) 1223b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 123a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(NumStart, I)); 1242f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner unsigned N = atoi(Codes.back().c_str()); 1252f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Check that this is a valid matching constraint! 1262f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| 1272f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Type != isInput) 1282f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner return true; // Invalid constraint number. 1292f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner 1302f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Note that operand #n has a matching input. 1312f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner ConstraintsSoFar[N].hasMatchingInput = true; 132a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else { 133a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Single letter constraint. 134a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(I, I+1)); 135a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 1363b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 137a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 138a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 139a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return false; 140a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner} 141a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 142a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattnerstd::vector<InlineAsm::ConstraintInfo> 143a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris LattnerInlineAsm::ParseConstraints(const std::string &Constraints) { 144a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::vector<ConstraintInfo> Result; 145a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 146a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Scan the constraints string. 147a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner for (std::string::const_iterator I = Constraints.begin(), 148a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner E = Constraints.end(); I != E; ) { 149a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ConstraintInfo Info; 150a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 151a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of this constraint. 152a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator ConstraintEnd = std::find(I, E, ','); 153a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 154a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == I || // Empty constraint like ",," 1552f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Info.Parse(std::string(I, ConstraintEnd), Result)) { 1562f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Result.clear(); // Erroneous constraint? 157f0b415f178615714de38fb8196f49d131e54274bChris Lattner break; 158f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 159a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 160a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Result.push_back(Info); 1613b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 162a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // ConstraintEnd may be either the next comma or the end of the string. In 163a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // the former case, we skip the comma. 164a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd; 165f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I != E) { 166f0b415f178615714de38fb8196f49d131e54274bChris Lattner ++I; 167f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I == E) { Result.clear(); break; } // don't allow "xyz," 168f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 169f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 170f0b415f178615714de38fb8196f49d131e54274bChris Lattner 171f0b415f178615714de38fb8196f49d131e54274bChris Lattner return Result; 172f0b415f178615714de38fb8196f49d131e54274bChris Lattner} 173f0b415f178615714de38fb8196f49d131e54274bChris Lattner 174f0b415f178615714de38fb8196f49d131e54274bChris Lattner 175f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// Verify - Verify that the specified constraint string is reasonable for the 176f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// specified function type, and otherwise validate the constraint string. 177f0b415f178615714de38fb8196f49d131e54274bChris Lattnerbool InlineAsm::Verify(const FunctionType *Ty, const std::string &ConstStr) { 178f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Ty->isVarArg()) return false; 179f0b415f178615714de38fb8196f49d131e54274bChris Lattner 180a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr); 181f0b415f178615714de38fb8196f49d131e54274bChris Lattner 182f0b415f178615714de38fb8196f49d131e54274bChris Lattner // Error parsing constraints. 183f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Constraints.empty() && !ConstStr.empty()) return false; 184f0b415f178615714de38fb8196f49d131e54274bChris Lattner 185f0b415f178615714de38fb8196f49d131e54274bChris Lattner unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; 186ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner unsigned NumIndirect = 0; 187f0b415f178615714de38fb8196f49d131e54274bChris Lattner 188f0b415f178615714de38fb8196f49d131e54274bChris Lattner for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { 189a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (Constraints[i].Type) { 190a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isOutput: 191ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) 192ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner return false; // outputs before inputs and clobbers. 19373d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (!Constraints[i].isIndirect) { 194a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++NumOutputs; 195a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 196a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 197ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner ++NumIndirect; 19873d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // FALLTHROUGH for Indirect Outputs. 199a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isInput: 2003b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (NumClobbers) return false; // inputs before clobbers. 2013b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumInputs; 2023b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 203a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isClobber: 2043b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumClobbers; 2053b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 2063b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2073b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2083b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 20996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner switch (NumOutputs) { 21096bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 0: 21196bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner if (Ty->getReturnType() != Type::VoidTy) return false; 21296bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 21396bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 1: 21496bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner if (isa<StructType>(Ty->getReturnType())) return false; 21596bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 21696bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner default: 21796bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner const StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); 21896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner if (STy == 0 || STy->getNumElements() != NumOutputs) 21996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner return false; 22096bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 22196bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner } 2223b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 2233b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (Ty->getNumParams() != NumInputs) return false; 22480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return true; 22580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 226af303d53e6013417d189621c75179df6c7cbdcdeReid Spencer 227