diff options
| author | Mark Seaborn <mseaborn@chromium.org> | 2013-05-30 13:08:26 -0700 |
|---|---|---|
| committer | Mark Seaborn <mseaborn@chromium.org> | 2013-05-30 13:08:26 -0700 |
| commit | f72e0b53e25548d6db9220a03a303e589c9773a4 (patch) | |
| tree | aaff14bd8167571353c50289b005bd0fe5c98925 /lib/Transforms/NaCl/ExpandArithWithOverflow.cpp | |
| parent | 663c1c948321264aceb07b86cfadcd06b3386e1e (diff) | |
PNaCl: Add a pass to expand out Clang's use of registers of struct type
Clang's implementation of C++ method pointers generates IR that uses
LLVM registers with struct type -- specifically, loads and stores of
struct values, and extractvalue instructions. See
lib/CodeGen/ItaniumCXXABI.cpp in Clang. Add a pass, ExpandStructRegs,
which expands out those uses.
Factor out a function from ExpandArithWithOverflow so that the two
passes can share some code.
BUG=https://code.google.com/p/nativeclient/issues/detail?id=3343
TEST=*.ll tests + trybots + GCC torture tests
Review URL: https://codereview.chromium.org/15692014
Diffstat (limited to 'lib/Transforms/NaCl/ExpandArithWithOverflow.cpp')
| -rw-r--r-- | lib/Transforms/NaCl/ExpandArithWithOverflow.cpp | 33 |
1 files changed, 6 insertions, 27 deletions
diff --git a/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp b/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp index e120b24293..1c879d524c 100644 --- a/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp +++ b/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp @@ -94,9 +94,10 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) { "*.with.overflow must be a constant"); } - Value *ArithResult = BinaryOperator::Create( + SmallVector<Value *, 2> Fields; + Fields.push_back(BinaryOperator::Create( (Mul ? Instruction::Mul : Instruction::Add), VariableArg, ConstantArg, - Call->getName() + ".arith", Call); + Call->getName() + ".arith", Call)); uint64_t ArgMax; if (Mul) { @@ -104,32 +105,10 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) { } else { ArgMax = UintTypeMax(Bits) - ConstantArg->getZExtValue(); } - Value *Overflow = new ICmpInst( + Fields.push_back(new ICmpInst( Call, CmpInst::ICMP_UGT, VariableArg, ConstantInt::get(IntTy, ArgMax), - Call->getName() + ".overflow"); - - for (Value::use_iterator FieldIter = Call->use_begin(), - E = Call->use_end(); FieldIter != E; ) { - User *U = *FieldIter++; - ExtractValueInst *Field = dyn_cast<ExtractValueInst>(U); - if (!Field) { - errs() << "Use: " << *U << "\n"; - report_fatal_error( - "ExpandArithWithOverflow: Use is not an extractvalue"); - } - if (Field->getNumIndices() != 1) { - report_fatal_error("ExpandArithWithOverflow: Unexpected indices"); - } - unsigned Index = Field->getIndices()[0]; - if (Index == 0) { - Field->replaceAllUsesWith(ArithResult); - } else if (Index == 1) { - Field->replaceAllUsesWith(Overflow); - } else { - report_fatal_error("ExpandArithWithOverflow: Unexpected index"); - } - Field->eraseFromParent(); - } + Call->getName() + ".overflow")); + ReplaceUsesOfStructWithFields(Call, Fields); Call->eraseFromParent(); } Intrinsic->eraseFromParent(); |
