Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,10 @@ class TargetInfo : public TransferrableTargetInfo,
ArrayRef<ConstraintInfo> OutputConstraints,
unsigned &Index) const;

std::string
simplifyConstraint(StringRef Constraint,
SmallVectorImpl<ConstraintInfo> *OutCons = nullptr) const;

// Constraint parm will be left pointing at the last character of
// the constraint. In practice, it won't be changed unless the
// constraint is longer than one character.
Expand Down
49 changes: 49 additions & 0 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TargetParser/TargetParser.h"
#include <cstdlib>
Expand Down Expand Up @@ -1042,3 +1043,51 @@ void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
*Target = *Src;
}

std::string
TargetInfo::simplifyConstraint(StringRef Constraint,
SmallVectorImpl<ConstraintInfo> *OutCons) const {
std::string Result;

for (const char *I = Constraint.begin(), *E = Constraint.end(); I < E; I++) {
switch (*I) {
default:
Result += convertConstraint(I);
break;
// Ignore these
case '*':
case '?':
case '!':
case '=': // Will see this and the following in mult-alt constraints.
case '+':
break;
case '#': // Ignore the rest of the constraint alternative.
while (I + 1 != E && I[1] != ',')
I++;
break;
case '&':
case '%':
Result += *I;
while (I + 1 != E && I[1] == *I)
I++;
break;
case ',':
Result += "|";
break;
case 'g':
Result += "imr";
break;
case '[': {
assert(OutCons &&
"Must pass output names to constraints with a symbolic name");
unsigned Index;
bool ResolveResult = resolveSymbolicName(I, *OutCons, Index);
assert(ResolveResult && "Could not resolve symbolic name");
(void)ResolveResult;
Result += llvm::utostr(Index);
break;
}
}
}
return Result;
}
58 changes: 4 additions & 54 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2471,56 +2471,6 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
CaseRangeBlock = SavedCRBlock;
}

static std::string
SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {
std::string Result;

while (*Constraint) {
switch (*Constraint) {
default:
Result += Target.convertConstraint(Constraint);
break;
// Ignore these
case '*':
case '?':
case '!':
case '=': // Will see this and the following in mult-alt constraints.
case '+':
break;
case '#': // Ignore the rest of the constraint alternative.
while (Constraint[1] && Constraint[1] != ',')
Constraint++;
break;
case '&':
case '%':
Result += *Constraint;
while (Constraint[1] && Constraint[1] == *Constraint)
Constraint++;
break;
case ',':
Result += "|";
break;
case 'g':
Result += "imr";
break;
case '[': {
assert(OutCons &&
"Must pass output names to constraints with a symbolic name");
unsigned Index;
bool result = Target.resolveSymbolicName(Constraint, *OutCons, Index);
assert(result && "Could not resolve symbolic name"); (void)result;
Result += llvm::utostr(Index);
break;
}
}

Constraint++;
}

return Result;
}

/// AddVariableConstraints - Look at AsmExpr and if it is a variable declared
/// as using a particular register add that as a constraint that will be used
/// in this asm stmt.
Expand Down Expand Up @@ -2899,8 +2849,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {

// Simplify the output constraint.
std::string OutputConstraint(S.getOutputConstraint(i));
OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1,
getTarget(), &OutputConstraintInfos);
OutputConstraint = getTarget().simplifyConstraint(
OutputConstraint.c_str() + 1, &OutputConstraintInfos);

const Expr *OutExpr = S.getOutputExpr(i);
OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
Expand Down Expand Up @@ -3062,8 +3012,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {

// Simplify the input constraint.
std::string InputConstraint(S.getInputConstraint(i));
InputConstraint = SimplifyConstraint(InputConstraint.c_str(), getTarget(),
&OutputConstraintInfos);
InputConstraint = getTarget().simplifyConstraint(InputConstraint.c_str(),
&OutputConstraintInfos);

InputConstraint = AddVariableConstraints(
InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()),
Expand Down
Loading