From 859fff476dfe8d83abdf4621b1d20062c0daa85c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 4 Sep 2009 12:08:11 +0000 Subject: Include optional subclass flags, such as inbounds, nsw, etc., in the Constant uniquing tables. This allows distinct ConstantExpr objects with the same operation and different flags. Even though a ConstantExpr "a + b" is either always overflowing or never overflowing (due to being a ConstantExpr), it's still necessary to be able to represent it both with and without overflow flags at the same time within the IR, because the safety of the flag may depend on the context of the use. If the constant really does overflow, it wouldn't ever be safe to use with the flag set, however the use may be in code that is never actually executed. This also makes it possible to merge all the flags tests into a single test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80998 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 56 ++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 9ed75ab131..05f7b52292 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -883,19 +883,6 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() { return false; } -static void SetOptimizationFlags(Value *V, uint64_t Flags) { - if (OverflowingBinaryOperator *OBO = - dyn_cast(V)) { - if (Flags & (1 << bitc::OBO_NO_SIGNED_WRAP)) - OBO->setHasNoSignedWrap(true); - if (Flags & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) - OBO->setHasNoUnsignedWrap(true); - } else if (SDivOperator *Div = dyn_cast(V)) { - if (Flags & (1 << bitc::SDIV_EXACT)) - Div->setIsExact(true); - } -} - bool BitcodeReader::ParseConstants() { if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) return Error("Malformed block record"); @@ -1047,10 +1034,22 @@ bool BitcodeReader::ParseConstants() { } else { Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy); - V = ConstantExpr::get(Opc, LHS, RHS); + unsigned Flags = 0; + if (Record.size() >= 4) { + if (Opc == Instruction::Add || + Opc == Instruction::Sub || + Opc == Instruction::Mul) { + if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP)) + Flags |= OverflowingBinaryOperator::NoSignedWrap; + if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) + Flags |= OverflowingBinaryOperator::NoUnsignedWrap; + } else if (Opc == Instruction::SDiv) { + if (Record[3] & (1 << bitc::SDIV_EXACT)) + Flags |= SDivOperator::IsExact; + } + } + V = ConstantExpr::get(Opc, LHS, RHS, Flags); } - if (Record.size() >= 4) - SetOptimizationFlags(V, Record[3]); break; } case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval] @@ -1075,10 +1074,12 @@ bool BitcodeReader::ParseConstants() { if (!ElTy) return Error("Invalid CE_GEP record"); Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy)); } - V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], - Elts.size()-1); if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP) - cast(V)->setIsInBounds(true); + V = ConstantExpr::getInBoundsGetElementPtr(Elts[0], &Elts[1], + Elts.size()-1); + else + V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], + Elts.size()-1); break; } case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#] @@ -1610,8 +1611,19 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType()); if (Opc == -1) return Error("Invalid BINOP record"); I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); - if (OpNum < Record.size()) - SetOptimizationFlags(I, Record[3]); + if (OpNum < Record.size()) { + if (Opc == Instruction::Add || + Opc == Instruction::Sub || + Opc == Instruction::Mul) { + if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP)) + cast(I)->setHasNoSignedWrap(true); + if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) + cast(I)->setHasNoUnsignedWrap(true); + } else if (Opc == Instruction::SDiv) { + if (Record[3] & (1 << bitc::SDIV_EXACT)) + cast(I)->setIsExact(true); + } + } break; } case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc] @@ -1645,7 +1657,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end()); if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP) - cast(I)->setIsInBounds(true); + cast(I)->setIsInBounds(true); break; } -- cgit v1.2.3-18-g5258