llvm.org GIT mirror llvm / 1cce5bf
Recommited r156374 with critical fixes in BitcodeReader/Writer: Ordinary patch for PR1255. Added new case-ranges orientated methods for adding/removing cases in SwitchInst. After this patch cases will internally representated as ConstantArray-s instead of ConstantInt, externally cases wrapped within the ConstantRangesSet object. Old methods of SwitchInst are also works well, but marked as deprecated. So on this stage we have no side effects except that I added support for case ranges in BitcodeReader/Writer, of course test for Bitcode is also added. Old "switch" format is also supported. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156704 91177308-0d34-0410-b5e6-96231b3b80d8 Stepan Dyatkovskiy 8 years ago
6 changed file(s) with 249 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
1919 #include "llvm/DerivedTypes.h"
2020 #include "llvm/Attributes.h"
2121 #include "llvm/CallingConv.h"
22 #include "llvm/Support/ConstantRangesSet.h"
23 #include "llvm/Support/CRSBuilder.h"
2224 #include "llvm/ADT/ArrayRef.h"
2325 #include "llvm/ADT/SmallVector.h"
2426 #include "llvm/Support/ErrorHandling.h"
24992501 }
25002502
25012503 /// Resolves case value for current case.
2504 /// @Deprecated
25022505 ConstantIntTy *getCaseValue() {
25032506 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2504 return reinterpret_cast(SI->getOperand(2 + Index*2));
2507 ConstantRangesSet CRS =
2508 reinterpret_cast(SI->getOperand(2 + Index*2));
2509 ConstantRangesSet::Range R = CRS.getItem(0);
2510 return R.Low;
2511 }
2512
2513 /// Resolves case value for current case.
2514 ConstantRangesSet getCaseValueEx() {
2515 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2516 return reinterpret_cast(SI->getOperand(2 + Index*2));
25052517 }
25062518
25072519 /// Resolves successor for current case.
25712583 CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
25722584
25732585 /// Sets the new value for current case.
2586 /// @Deprecated.
25742587 void setValue(ConstantInt *V) {
25752588 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2576 SI->setOperand(2 + Index*2, reinterpret_cast(V));
2589 CRSBuilder CB;
2590 CB.add(V);
2591 SI->setOperand(2 + Index*2,
2592 reinterpret_cast((Constant*)CB.getCase()));
2593 }
2594
2595 /// Sets the new value for current case.
2596 void setValueEx(ConstantRangesSet& V) {
2597 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2598 SI->setOperand(2 + Index*2, reinterpret_cast((Constant*)V));
25772599 }
25782600
25792601 /// Sets the new successor for current case.
26532675 /// that it is handled by the default handler.
26542676 CaseIt findCaseValue(const ConstantInt *C) {
26552677 for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
2656 if (i.getCaseValue() == C)
2678 if (i.getCaseValueEx().isSatisfies(C))
26572679 return i;
26582680 return case_default();
26592681 }
26602682 ConstCaseIt findCaseValue(const ConstantInt *C) const {
26612683 for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
2662 if (i.getCaseValue() == C)
2684 if (i.getCaseValueEx().isSatisfies(C))
26632685 return i;
26642686 return case_default();
26652687 }
26802702 }
26812703
26822704 /// addCase - Add an entry to the switch instruction...
2705 /// @Deprecated
26832706 /// Note:
26842707 /// This action invalidates case_end(). Old case_end() iterator will
26852708 /// point to the added case.
26862709 void addCase(ConstantInt *OnVal, BasicBlock *Dest);
2710
2711 /// addCase - Add an entry to the switch instruction.
2712 /// Note:
2713 /// This action invalidates case_end(). Old case_end() iterator will
2714 /// point to the added case.
2715 void addCase(ConstantRangesSet& OnVal, BasicBlock *Dest);
26872716
26882717 /// removeCase - This method removes the specified case and its successor
26892718 /// from the switch instruction. Note that this operation may reorder the
27022731 assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
27032732 setOperand(idx*2+1, (Value*)NewSucc);
27042733 }
2734
2735 uint16_t Hash() const {
2736 uint32_t NumberOfCases = (uint32_t)getNumCases();
2737 uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16);
2738 for (ConstCaseIt i = case_begin(), e = case_end();
2739 i != e; ++i) {
2740 uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems();
2741 Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16);
2742 }
2743 return Hash;
2744 }
27052745
27062746 // Methods for support type inquiry through isa, cast, and dyn_cast:
27072747 static inline bool classof(const SwitchInst *) { return true; }
4747 Constant *Array;
4848 public:
4949
50 bool IsWide;
51
5052 // implicit
51 ConstantRangesSet(Constant *V) : Array(V) {}
53 ConstantRangesSet(Constant *V) : Array(V) {
54 ArrayType *ArrTy = cast(Array->getType());
55 VectorType *VecTy = cast(ArrTy->getElementType());
56 IntegerType *IntTy = cast(VecTy->getElementType());
57 IsWide = IntTy->getBitWidth() > 64;
58 }
5259
5360 operator Constant*() { return Array; }
5461 operator const Constant*() const { return Array; }
229236 return cast(Array->getType())->getNumElements();
230237 }
231238
239 bool isWideNumberFormat() const { return IsWide; }
240
241 bool isSingleNumber(unsigned idx) const {
242 Constant *CV = Array->getAggregateElement(idx);
243 return cast(CV->getType())->getNumElements() == 1;
244 }
245
232246 /// Returns set the size, that equals number of all values + sizes of all
233247 /// ranges.
234248 /// Ranges set is considered as flat numbers collection.
2626 #include "llvm/Support/MemoryBuffer.h"
2727 #include "llvm/OperandTraits.h"
2828 using namespace llvm;
29
30 enum {
31 SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
32 };
2933
3034 void BitcodeReader::materializeForwardReferencedFunctions() {
3135 while (!BlockAddrFwdRefs.empty()) {
926930 return false;
927931 }
928932
933 APInt ReadWideAPInt(const uint64_t *Vals, unsigned ActiveWords,
934 unsigned TypeBits) {
935 SmallVector Words;
936 Words.resize(ActiveWords);
937 for (unsigned i = 0; i != ActiveWords; ++i)
938 Words[i] = DecodeSignRotatedValue(Vals[i]);
939
940 return APInt(TypeBits, Words);
941 }
942
929943 bool BitcodeReader::ParseConstants() {
930944 if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
931945 return Error("Malformed block record");
982996 return Error("Invalid WIDE_INTEGER record");
983997
984998 unsigned NumWords = Record.size();
985 SmallVector Words;
986 Words.resize(NumWords);
987 for (unsigned i = 0; i != NumWords; ++i)
988 Words[i] = DecodeSignRotatedValue(Record[i]);
989 V = ConstantInt::get(Context,
990 APInt(cast(CurTy)->getBitWidth(),
991 Words));
999
1000 APInt VInt = ReadWideAPInt(&Record[0], NumWords,
1001 cast(CurTy)->getBitWidth());
1002 V = ConstantInt::get(Context, VInt);
1003
9921004 break;
9931005 }
9941006 case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
22202232 break;
22212233 }
22222234 case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
2235 // Check magic
2236 if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
2237 // New SwitchInst format with case ranges.
2238
2239 Type *OpTy = getTypeByID(Record[1]);
2240 unsigned ValueBitWidth = cast(OpTy)->getBitWidth();
2241
2242 Value *Cond = getFnValueByID(Record[2], OpTy);
2243 BasicBlock *Default = getBasicBlock(Record[3]);
2244 if (OpTy == 0 || Cond == 0 || Default == 0)
2245 return Error("Invalid SWITCH record");
2246
2247 unsigned NumCases = Record[4];
2248
2249 SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
2250 InstructionList.push_back(SI);
2251
2252 unsigned CurIdx = 5;
2253 for (unsigned i = 0; i != NumCases; ++i) {
2254 CRSBuilder CaseBuilder;
2255 unsigned NumItems = Record[CurIdx++];
2256 for (unsigned ci = 0; ci != NumItems; ++ci) {
2257 bool isSingleNumber = Record[CurIdx++];
2258
2259 APInt Low;
2260 unsigned ActiveWords = 1;
2261 if (ValueBitWidth > 64)
2262 ActiveWords = Record[CurIdx++];
2263 Low = ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
2264 CurIdx += ActiveWords;
2265
2266 if (!isSingleNumber) {
2267 ActiveWords = 1;
2268 if (ValueBitWidth > 64)
2269 ActiveWords = Record[CurIdx++];
2270 APInt High =
2271 ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
2272 CaseBuilder.add(cast(ConstantInt::get(OpTy, Low)),
2273 cast(ConstantInt::get(OpTy, High)));
2274 CurIdx += ActiveWords;
2275 } else
2276 CaseBuilder.add(cast(ConstantInt::get(OpTy, Low)));
2277 }
2278 BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
2279 ConstantRangesSet Case = CaseBuilder.getCase();
2280 SI->addCase(Case, DestBB);
2281 }
2282 uint16_t Hash = SI->Hash();
2283 if (Hash != (Record[0] & 0xFFFF))
2284 return Error("Invalid SWITCH record");
2285 I = SI;
2286 break;
2287 }
2288
2289 // Old SwitchInst format without case ranges.
2290
22232291 if (Record.size() < 3 || (Record.size() & 1) == 0)
22242292 return Error("Invalid SWITCH record");
22252293 Type *OpTy = getTypeByID(Record[0]);
6161 FUNCTION_INST_CAST_ABBREV,
6262 FUNCTION_INST_RET_VOID_ABBREV,
6363 FUNCTION_INST_RET_VAL_ABBREV,
64 FUNCTION_INST_UNREACHABLE_ABBREV
64 FUNCTION_INST_UNREACHABLE_ABBREV,
65
66 // SwitchInst Magic
67 SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
6568 };
6669
6770 static unsigned GetEncodedCastOpcode(unsigned Opcode) {
718721 Stream.ExitBlock();
719722 }
720723
724 static void EmitAPInt(SmallVectorImpl &Vals,
725 unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
726 bool EmitSizeForWideNumbers = false
727 ) {
728 if (Val.getBitWidth() <= 64) {
729 uint64_t V = Val.getSExtValue();
730 if ((int64_t)V >= 0)
731 Vals.push_back(V << 1);
732 else
733 Vals.push_back((-V << 1) | 1);
734 Code = bitc::CST_CODE_INTEGER;
735 AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
736 } else {
737 // Wide integers, > 64 bits in size.
738 // We have an arbitrary precision integer value to write whose
739 // bit width is > 64. However, in canonical unsigned integer
740 // format it is likely that the high bits are going to be zero.
741 // So, we only write the number of active words.
742 unsigned NWords = Val.getActiveWords();
743
744 if (EmitSizeForWideNumbers)
745 Vals.push_back(NWords);
746
747 const uint64_t *RawWords = Val.getRawData();
748 for (unsigned i = 0; i != NWords; ++i) {
749 int64_t V = RawWords[i];
750 if (V >= 0)
751 Vals.push_back(V << 1);
752 else
753 Vals.push_back((-V << 1) | 1);
754 }
755 Code = bitc::CST_CODE_WIDE_INTEGER;
756 }
757 }
758
721759 static void WriteConstants(unsigned FirstVal, unsigned LastVal,
722760 const ValueEnumerator &VE,
723761 BitstreamWriter &Stream, bool isGlobal) {
800838 } else if (isa(C)) {
801839 Code = bitc::CST_CODE_UNDEF;
802840 } else if (const ConstantInt *IV = dyn_cast(C)) {
803 if (IV->getBitWidth() <= 64) {
804 uint64_t V = IV->getSExtValue();
805 if ((int64_t)V >= 0)
806 Record.push_back(V << 1);
807 else
808 Record.push_back((-V << 1) | 1);
809 Code = bitc::CST_CODE_INTEGER;
810 AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
811 } else { // Wide integers, > 64 bits in size.
812 // We have an arbitrary precision integer value to write whose
813 // bit width is > 64. However, in canonical unsigned integer
814 // format it is likely that the high bits are going to be zero.
815 // So, we only write the number of active words.
816 unsigned NWords = IV->getValue().getActiveWords();
817 const uint64_t *RawWords = IV->getValue().getRawData();
818 for (unsigned i = 0; i != NWords; ++i) {
819 int64_t V = RawWords[i];
820 if (V >= 0)
821 Record.push_back(V << 1);
822 else
823 Record.push_back((-V << 1) | 1);
824 }
825 Code = bitc::CST_CODE_WIDE_INTEGER;
826 }
841 EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
827842 } else if (const ConstantFP *CFP = dyn_cast(C)) {
828843 Code = bitc::CST_CODE_FLOAT;
829844 Type *Ty = CFP->getType();
11361151 break;
11371152 case Instruction::Switch:
11381153 {
1154 // Redefine Vals, since here we need to use 64 bit values
1155 // explicitly to store large APInt numbers.
1156 SmallVector Vals64;
1157
11391158 Code = bitc::FUNC_CODE_INST_SWITCH;
11401159 SwitchInst &SI = cast(I);
1141 Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
1142 Vals.push_back(VE.getValueID(SI.getCondition()));
1143 Vals.push_back(VE.getValueID(SI.getDefaultDest()));
1160
1161 uint32_t SwitchRecordHeader = SI.Hash() | (SWITCH_INST_MAGIC << 16);
1162 Vals64.push_back(SwitchRecordHeader);
1163
1164 Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
1165 Vals64.push_back(VE.getValueID(SI.getCondition()));
1166 Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
1167 Vals64.push_back(SI.getNumCases());
11441168 for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
11451169 i != e; ++i) {
1146 Vals.push_back(VE.getValueID(i.getCaseValue()));
1147 Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
1170 ConstantRangesSet CRS = i.getCaseValueEx();
1171 Vals64.push_back(CRS.getNumItems());
1172 for (unsigned ri = 0, rn = CRS.getNumItems(); ri != rn; ++ri) {
1173 ConstantRangesSet::Range r = CRS.getItem(ri);
1174
1175 Vals64.push_back(CRS.isSingleNumber(ri));
1176
1177 const APInt &Low = r.Low->getValue();
1178 const APInt &High = r.High->getValue();
1179 unsigned Code, Abbrev; // will unused.
1180
1181 EmitAPInt(Vals64, Code, Abbrev, Low, true);
1182 if (r.Low != r.High)
1183 EmitAPInt(Vals64, Code, Abbrev, High, true);
1184 }
1185 Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
11481186 }
1187
1188 Stream.EmitRecord(Code, Vals64, AbbrevToUse);
1189
1190 // Also do expected action - clear external Vals collection:
1191 Vals.clear();
1192 return;
11491193 }
11501194 break;
11511195 case Instruction::IndirectBr:
31683168 /// addCase - Add an entry to the switch instruction...
31693169 ///
31703170 void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
3171 CRSBuilder CB;
3172 CB.add(OnVal);
3173 ConstantRangesSet CRS = CB.getCase();
3174 addCase(CRS, Dest);
3175 }
3176
3177 void SwitchInst::addCase(ConstantRangesSet& OnVal, BasicBlock *Dest) {
31713178 unsigned NewCaseIdx = getNumCases();
31723179 unsigned OpNo = NumOperands;
31733180 if (OpNo+2 > ReservedSpace)
31763183 assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
31773184 NumOperands = OpNo+2;
31783185 CaseIt Case(this, NewCaseIdx);
3179 Case.setValue(OnVal);
3186 Case.setValueEx(OnVal);
31803187 Case.setSuccessor(Dest);
31813188 }
31823189
0 ; RUN: rm -f %t.bc
1 ; RUN: rm -f %t.ll
2 ; RUN: rm -f %t2.bc
3 ; RUN: rm -f %t2.ll
4 ; RUN: llvm-as %s -o %t.bc
5 ; RUN: llvm-dis %t.bc -o - | tail -n +2 > %t.ll
6 ; RUN: llvm-as %t.ll -o %t2.bc
7 ; RUN: llvm-dis %t2.bc -o - | tail -n +2 > %t2.ll
8 ; RUN: diff %t.ll %t2.ll | not grep .*
9
10 define void @test() {
11 %mem = alloca i32
12 store i32 2, i32* %mem
13 %c = load i32* %mem
14 switch i32 %c, label %exit [
15 i32 1, label %exit
16 i32 2, label %exit
17 ]
18 exit:
19 ret void
20 }
21 define void @test_wide() {
22 %mem = alloca i256
23 store i256 2, i256* %mem
24 %c = load i256* %mem
25 switch i256 %c, label %exit [
26 i256 123456789012345678901234567890, label %exit
27 i256 2, label %exit
28 ]
29 exit:
30 ret void
31 }
32