llvm.org GIT mirror llvm / 85a4406
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@156374 91177308-0d34-0410-b5e6-96231b3b80d8 Stepan Dyatkovskiy 8 years ago
6 changed file(s) with 236 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
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.
1919 #include "llvm/DerivedTypes.h"
2020 #include "llvm/Attributes.h"
2121 #include "llvm/CallingConv.h"
22 #include "llvm/ConstantRangesSet.h"
23 #include "llvm/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; }
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()) {
976980 return false;
977981 }
978982
983 template
984 APInt ReadWideAPInt(const intty *Vals, unsigned ActiveWords,
985 unsigned TypeBits) {
986 SmallVector Words;
987 Words.resize(ActiveWords);
988 for (unsigned i = 0; i != ActiveWords; ++i)
989 Words[i] = DecodeSignRotatedValue(Vals[i]);
990
991 return APInt(TypeBits, Words);
992 }
993
979994 bool BitcodeReader::ParseConstants() {
980995 if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
981996 return Error("Malformed block record");
10321047 return Error("Invalid WIDE_INTEGER record");
10331048
10341049 unsigned NumWords = Record.size();
1035 SmallVector Words;
1036 Words.resize(NumWords);
1037 for (unsigned i = 0; i != NumWords; ++i)
1038 Words[i] = DecodeSignRotatedValue(Record[i]);
1039 V = ConstantInt::get(Context,
1040 APInt(cast(CurTy)->getBitWidth(),
1041 Words));
1050
1051 APInt VInt = ReadWideAPInt(&Record[0], NumWords,
1052 cast(CurTy)->getBitWidth());
1053 V = ConstantInt::get(Context, VInt);
1054
10421055 break;
10431056 }
10441057 case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
22702283 break;
22712284 }
22722285 case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
2286 // Check magic
2287 if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
2288 // New SwitchInst format with case ranges.
2289
2290 Type *OpTy = getTypeByID(Record[1]);
2291 unsigned ValueBitWidth = cast(OpTy)->getBitWidth();
2292
2293 Value *Cond = getFnValueByID(Record[2], OpTy);
2294 BasicBlock *Default = getBasicBlock(Record[3]);
2295 if (OpTy == 0 || Cond == 0 || Default == 0)
2296 return Error("Invalid SWITCH record");
2297
2298 unsigned NumCases = Record[4];
2299
2300 SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
2301
2302 unsigned CurIdx = 5;
2303 for (unsigned i = 0; i != NumCases; ++i) {
2304 CRSBuilder CaseBuilder;
2305 unsigned NumItems = Record[CurIdx++];
2306 for (unsigned ci = 0; ci != NumItems; ++ci) {
2307 bool isSingleNumber = Record[CurIdx++];
2308
2309 APInt Low;
2310 unsigned ActiveWords = 1;
2311 if (ValueBitWidth > 64)
2312 ActiveWords = Record[CurIdx++];
2313 Low = ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
2314 CurIdx += ActiveWords;
2315
2316 if (!isSingleNumber) {
2317 ActiveWords = 1;
2318 if (ValueBitWidth > 64)
2319 ActiveWords = Record[CurIdx++];
2320 APInt High =
2321 ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
2322 CaseBuilder.add(cast(ConstantInt::get(OpTy, Low)),
2323 cast(ConstantInt::get(OpTy, High)));
2324 CurIdx += ActiveWords;
2325 } else
2326 CaseBuilder.add(cast(ConstantInt::get(OpTy, Low)));
2327 }
2328 BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
2329 ConstantRangesSet Case = CaseBuilder.getCase();
2330 SI->addCase(Case, DestBB);
2331 }
2332 uint16_t Hash = SI->Hash();
2333 if (Hash != (Record[0] & 0xFFFF))
2334 return Error("Invalid SWITCH record");
2335 I = SI;
2336 break;
2337 }
2338
2339 // Old SwitchInst format without case ranges.
2340
22732341 if (Record.size() < 3 || (Record.size() & 1) == 0)
22742342 return Error("Invalid SWITCH record");
22752343 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 template
725 static void EmitAPInt(SmallVectorImpl &Vals,
726 unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
727 bool EmitSizeForWideNumbers = false
728 ) {
729 if (Val.getBitWidth() <= 64) {
730 uint64_t V = Val.getSExtValue();
731 if ((int64_t)V >= 0)
732 Vals.push_back(V << 1);
733 else
734 Vals.push_back((-V << 1) | 1);
735 Code = bitc::CST_CODE_INTEGER;
736 AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
737 } else {
738 // Wide integers, > 64 bits in size.
739 // We have an arbitrary precision integer value to write whose
740 // bit width is > 64. However, in canonical unsigned integer
741 // format it is likely that the high bits are going to be zero.
742 // So, we only write the number of active words.
743 unsigned NWords = Val.getActiveWords();
744
745 if (EmitSizeForWideNumbers)
746 Vals.push_back(NWords);
747
748 const uint64_t *RawWords = Val.getRawData();
749 for (unsigned i = 0; i != NWords; ++i) {
750 int64_t V = RawWords[i];
751 if (V >= 0)
752 Vals.push_back(V << 1);
753 else
754 Vals.push_back((-V << 1) | 1);
755 }
756 Code = bitc::CST_CODE_WIDE_INTEGER;
757 }
758 }
759
721760 static void WriteConstants(unsigned FirstVal, unsigned LastVal,
722761 const ValueEnumerator &VE,
723762 BitstreamWriter &Stream, bool isGlobal) {
800839 } else if (isa(C)) {
801840 Code = bitc::CST_CODE_UNDEF;
802841 } 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 }
842 EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
827843 } else if (const ConstantFP *CFP = dyn_cast(C)) {
828844 Code = bitc::CST_CODE_FLOAT;
829845 Type *Ty = CFP->getType();
11381154 {
11391155 Code = bitc::FUNC_CODE_INST_SWITCH;
11401156 SwitchInst &SI = cast(I);
1157
1158 uint32_t SwitchRecordHeader = SI.Hash() | (SWITCH_INST_MAGIC << 16);
1159 Vals.push_back(SwitchRecordHeader);
1160
11411161 Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
11421162 Vals.push_back(VE.getValueID(SI.getCondition()));
11431163 Vals.push_back(VE.getValueID(SI.getDefaultDest()));
1164 Vals.push_back(SI.getNumCases());
11441165 for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
11451166 i != e; ++i) {
1146 Vals.push_back(VE.getValueID(i.getCaseValue()));
1167 ConstantRangesSet CRS = i.getCaseValueEx();
1168 Vals.push_back(CRS.getNumItems());
1169 for (unsigned ri = 0, rn = CRS.getNumItems(); ri != rn; ++ri) {
1170 ConstantRangesSet::Range r = CRS.getItem(ri);
1171
1172 Vals.push_back(CRS.isSingleNumber(ri));
1173
1174 const APInt &Low = r.Low->getValue();
1175 const APInt &High = r.High->getValue();
1176 unsigned Code, Abbrev; // will unused.
1177
1178 EmitAPInt(Vals, Code, Abbrev, Low, true);
1179 if (r.Low != r.High)
1180 EmitAPInt(Vals, Code, Abbrev, High, true);
1181 }
11471182 Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
11481183 }
11491184 }
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