From 367f109ba954239a348c624a3331422bfdb31d03 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 29 Jan 2007 23:45:14 +0000 Subject: [PATCH] add initial support for handling inline asms with multiple constraints. This doesn't do the "right thing" but will probably work in most cases. This implements CodeGen/PowerPC/2007-01-29-lbrx-asm.ll. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33643 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3b452979aa5..da351bbdf11 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2433,6 +2433,44 @@ GetRegistersForValue(const std::string &ConstrCode, return RegsForValue(); } +/// getConstraintGenerality - Return an integer indicating how general CT is. +static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) { + switch (CT) { + default: assert(0 && "Unknown constraint type!"); + case TargetLowering::C_Other: + case TargetLowering::C_Unknown: + return 0; + case TargetLowering::C_Register: + return 1; + case TargetLowering::C_RegisterClass: + return 2; + case TargetLowering::C_Memory: + return 3; + } +} + +static std::string GetMostGeneralConstraint(std::vector &C, + const TargetLowering &TLI) { + assert(!C.empty() && "Must have at least one constraint"); + if (C.size() == 1) return C[0]; + + std::string *Current = &C[0]; + // If we have multiple constraints, try to pick the most general one ahead + // of time. This isn't a wonderful solution, but handles common cases. + TargetLowering::ConstraintType Flavor = TLI.getConstraintType(Current[0][0]); + for (unsigned j = 1, e = C.size(); j != e; ++j) { + TargetLowering::ConstraintType ThisFlavor = TLI.getConstraintType(C[j][0]); + if (getConstraintGenerality(ThisFlavor) > + getConstraintGenerality(Flavor)) { + // This constraint letter is more general than the previous one, + // use it. + Flavor = ThisFlavor; + Current = &C[j]; + } + } + return *Current; +} + /// visitInlineAsm - Handle a call to an InlineAsm object. /// @@ -2462,8 +2500,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { std::set OutputRegs, InputRegs; unsigned OpNum = 1; for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { - assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); - std::string &ConstraintCode = Constraints[i].Codes[0]; + std::string ConstraintCode = + GetMostGeneralConstraint(Constraints[i].Codes, TLI); MVT::ValueType OpVT; @@ -2527,8 +2565,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { OpNum = 1; for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { - assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); - std::string &ConstraintCode = Constraints[i].Codes[0]; + std::string ConstraintCode = + GetMostGeneralConstraint(Constraints[i].Codes, TLI); switch (Constraints[i].Type) { case InlineAsm::isOutput: { -- 2.34.1