Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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(
StringRef(OutputConstraint).substr(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, &OutputConstraintInfos);

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