[llvm-commits] [dragonegg] r126434 - /dragonegg/trunk/llvm-convert.cpp
Duncan Sands
baldrick at free.fr
Thu Feb 24 13:24:13 PST 2011
Author: baldrick
Date: Thu Feb 24 15:24:13 2011
New Revision: 126434
URL: http://llvm.org/viewvc/llvm-project?rev=126434&view=rev
Log:
Allocate memory for replacement strings (produced when parsing multiple
alternative asm constraints) using a BumpPtrAllocator, rather than a hand
crafted storage pool. This removes the danger of accidentally forgetting
to free the memory.
Modified:
dragonegg/trunk/llvm-convert.cpp
Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=126434&r1=126433&r2=126434&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Thu Feb 24 15:24:13 2011
@@ -3349,10 +3349,9 @@
/// gcc's algorithm for picking "the best" tuple is quite complicated, and
/// is performed after things like SROA, not before. At the moment we are
/// just trying to pick one that will work. This may get refined.
-static void
-ChooseConstraintTuple(gimple stmt, const char **Constraints,
- unsigned NumChoices, const char **ReplacementStrings)
-{
+static void ChooseConstraintTuple(gimple stmt, const char **Constraints,
+ unsigned NumChoices,
+ BumpPtrAllocator &ReplacementStrings) {
unsigned NumInputs = gimple_asm_ninputs(stmt);
unsigned NumOutputs = gimple_asm_noutputs(stmt);
@@ -3437,27 +3436,19 @@
// For outputs, copy the leading = or +.
char *newstring;
if (i<NumOutputs) {
- newstring = (char *)xmalloc(end-start+1+1);
+ newstring = ReplacementStrings.Allocate<char>(end-start+1+1);
newstring[0] = *(Constraints[i]);
strncpy(newstring+1, start, end-start);
newstring[end-start+1] = 0;
} else {
- newstring = (char *)xmalloc(end-start+1);
+ newstring = ReplacementStrings.Allocate<char>(end-start+1);
strncpy(newstring, start, end-start);
newstring[end-start] = 0;
}
Constraints[i] = (const char *)newstring;
- ReplacementStrings[i] = (const char*)newstring;
}
}
-static void FreeConstTupleStrings(const char **ReplacementStrings,
- unsigned int Size) {
- if (ReplacementStrings)
- for (unsigned int i=0; i<Size; i++)
- free(const_cast<char *>(ReplacementStrings[i]));
-}
-
//===----------------------------------------------------------------------===//
// ... Helpers for Builtin Function Expansion ...
@@ -6748,6 +6739,33 @@
const unsigned NumInputs = gimple_asm_ninputs(stmt);
const unsigned NumClobbers = gimple_asm_nclobbers (stmt);
+ /// Constraints - The output/input constraints, concatenated together in array
+ /// form instead of list form. This way of doing things is forced on us by
+ /// GCC routines like parse_output_constraint which rummage around inside the
+ /// array.
+ const char **Constraints =
+ (const char **)alloca((NumOutputs + NumInputs) * sizeof(const char *));
+
+ // Initialize the Constraints array.
+ for (unsigned i = 0; i != NumOutputs; ++i) {
+ tree Output = gimple_asm_output_op(stmt, i);
+ // If there's an erroneous arg then bail out.
+ if (TREE_TYPE(TREE_VALUE(Output)) == error_mark_node) return;
+ // Record the output constraint.
+ const char *Constraint =
+ TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Output)));
+ Constraints[i] = Constraint;
+ }
+ for (unsigned i = 0; i != NumInputs; ++i) {
+ tree Input = gimple_asm_input_op(stmt, i);
+ // If there's an erroneous arg then bail out.
+ if (TREE_TYPE(TREE_VALUE(Input)) == error_mark_node) return;
+ // Record the input constraint.
+ const char *Constraint =
+ TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Input)));
+ Constraints[NumOutputs+i] = Constraint;
+ }
+
// Look for multiple alternative constraints: multiple alternatives separated
// by commas.
unsigned NumChoices = 0; // sentinal; real value is always at least 1.
@@ -6776,42 +6794,12 @@
NumChoices = NumOutputChoices;
}
- /// Constraints - The output/input constraints, concatenated together in array
- /// form instead of list form. This way of doing things is forced on us by
- /// GCC routines like parse_output_constraint which rummage around inside the
- /// array.
- const char **Constraints =
- (const char **)alloca((NumOutputs + NumInputs) * sizeof(const char *));
-
- // Initialize the Constraints array.
- for (unsigned i = 0; i != NumOutputs; ++i) {
- tree Output = gimple_asm_output_op(stmt, i);
- // If there's an erroneous arg then bail out.
- if (TREE_TYPE(TREE_VALUE(Output)) == error_mark_node) return;
- // Record the output constraint.
- const char *Constraint =
- TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Output)));
- Constraints[i] = Constraint;
- }
- for (unsigned i = 0; i != NumInputs; ++i) {
- tree Input = gimple_asm_input_op(stmt, i);
- // If there's an erroneous arg then bail out.
- if (TREE_TYPE(TREE_VALUE(Input)) == error_mark_node) return;
- // Record the input constraint.
- const char *Constraint =
- TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Input)));
- Constraints[NumOutputs+i] = Constraint;
- }
-
// If there are multiple constraint tuples, pick one. Constraints is
// altered to point to shorter strings (which are malloc'ed), and everything
// below Just Works as in the NumChoices==1 case.
- const char** ReplacementStrings = 0;
- if (NumChoices>1) {
- ReplacementStrings =
- (const char **)alloca((NumOutputs + NumInputs) * sizeof(const char *));
+ BumpPtrAllocator ReplacementStrings;
+ if (NumChoices > 1)
ChooseConstraintTuple(stmt, Constraints, NumChoices, ReplacementStrings);
- }
std::vector<Value*> CallOps;
std::vector<const Type*> CallArgTypes;
@@ -6835,10 +6823,8 @@
const char *Constraint = Constraints[i];
bool IsInOut, AllowsReg, AllowsMem;
if (!parse_output_constraint(&Constraint, i, NumInputs, NumOutputs,
- &AllowsMem, &AllowsReg, &IsInOut)) {
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
+ &AllowsMem, &AllowsReg, &IsInOut))
return;
- }
assert(Constraint[0] == '=' && "Not an output constraint?");
assert(!IsInOut && "asm expression not gimplified?");
@@ -6914,10 +6900,8 @@
bool AllowsReg, AllowsMem;
if (!parse_input_constraint(Constraints+NumOutputs+i, i,
NumInputs, NumOutputs, 0,
- Constraints, &AllowsMem, &AllowsReg)) {
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
+ Constraints, &AllowsMem, &AllowsReg))
return;
- }
bool isIndirect = false;
if (AllowsReg || !AllowsMem) { // Register operand.
const Type *LLVMTy = ConvertType(type);
@@ -6992,7 +6976,6 @@
error_at(gimple_location(stmt),
"unsupported inline asm: input constraint with a matching "
"output constraint of incompatible type!");
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return;
}
unsigned OTyBits = TD.getTypeSizeInBits(OTy);
@@ -7012,7 +6995,6 @@
error_at(gimple_location(stmt),
"unsupported inline asm: input constraint with a matching "
"output constraint of incompatible type!");
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return;
} else if (OTyBits > OpTyBits) {
Op = CastToAnyType(Op, !TYPE_UNSIGNED(type),
@@ -7105,7 +7087,6 @@
case -2: // Invalid.
error_at(gimple_location(stmt), "unknown register name %qs in %<asm%>",
RegName);
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return;
case -3: // cc
ConstraintStr += ",~{cc}";
@@ -7143,7 +7124,6 @@
// Make sure we're created a valid inline asm expression.
if (!InlineAsm::Verify(FTy, ConstraintStr)) {
error_at(gimple_location(stmt), "Invalid or unsupported inline assembly!");
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return;
}
@@ -7176,8 +7156,6 @@
// llvm.bswap.
if (const TargetLowering *TLI = TheTarget->getTargetLowering())
TLI->ExpandInlineAsm(CV);
-
- FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
}
void TreeToLLVM::RenderGIMPLE_ASSIGN(gimple stmt) {
More information about the llvm-commits
mailing list