llvm.org GIT mirror llvm / release_16 include / llvm / CodeGen / SelectionDAGNodes.h
release_16

Tree @release_16 (Download .tar.gz)

SelectionDAGNodes.h @release_16raw · history · blame

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
//===-- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the SDNode class and derived classes, which are used to
// represent the nodes and operations present in a SelectionDAG.  These nodes
// and operations are machine code level operations, with some similarities to
// the GCC RTL representation.
//
// Clients should include the SelectionDAG.h file instead of this file directly.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
#define LLVM_CODEGEN_SELECTIONDAGNODES_H

#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Value.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <vector>

namespace llvm {

class SelectionDAG;
class GlobalValue;
class MachineBasicBlock;
class SDNode;
template <typename T> struct simplify_type;

/// ISD namespace - This namespace contains an enum which represents all of the
/// SelectionDAG node types and value types.
///
namespace ISD {
  //===--------------------------------------------------------------------===//
  /// ISD::NodeType enum - This enum defines all of the operators valid in a
  /// SelectionDAG.
  ///
  enum NodeType {
    // EntryToken - This is the marker used to indicate the start of the region.
    EntryToken,

    // Token factor - This node takes multiple tokens as input and produces a
    // single token result.  This is used to represent the fact that the operand
    // operators are independent of each other.
    TokenFactor,
    
    // AssertSext, AssertZext - These nodes record if a register contains a 
    // value that has already been zero or sign extended from a narrower type.  
    // These nodes take two operands.  The first is the node that has already 
    // been extended, and the second is a value type node indicating the width
    // of the extension
    AssertSext, AssertZext,

    // Various leaf nodes.
    Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool,
    BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register,
    
    // TargetConstant - Like Constant, but the DAG does not do any folding or
    // simplification of the constant.  This is used by the DAG->DAG selector.
    TargetConstant,
    
    // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
    // anything else with this node, and this is valid in the target-specific
    // dag, turning into a GlobalAddress operand.
    TargetGlobalAddress,
    TargetFrameIndex,
    TargetConstantPool,
    TargetExternalSymbol,

    // CopyToReg - This node has three operands: a chain, a register number to
    // set to this value, and a value.  
    CopyToReg,

    // CopyFromReg - This node indicates that the input value is a virtual or
    // physical register that is defined outside of the scope of this
    // SelectionDAG.  The register is available from the RegSDNode object.
    CopyFromReg,

    // ImplicitDef - This node indicates that the specified register is
    // implicitly defined by some operation (e.g. its a live-in argument).  The
    // two operands to this are the token chain coming in and the register.
    // The only result is the token chain going out.
    ImplicitDef,

    // UNDEF - An undefined node
    UNDEF,

    // EXTRACT_ELEMENT - This is used to get the first or second (determined by
    // a Constant, which is required to be operand #1), element of the aggregate
    // value specified as operand #0.  This is only for use before legalization,
    // for values that will be broken into multiple registers.
    EXTRACT_ELEMENT,

    // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.  Given
    // two values of the same integer value type, this produces a value twice as
    // big.  Like EXTRACT_ELEMENT, this can only be used before legalization.
    BUILD_PAIR,


    // Simple integer binary arithmetic operators.
    ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
    
    // Simple binary floating point operators.
    FADD, FSUB, FMUL, FDIV, FREM,

    // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
    // an unsigned/signed value of type i[2*n], then return the top part.
    MULHU, MULHS,

    // Bitwise operators.
    AND, OR, XOR, SHL, SRA, SRL,

    // Counting operators
    CTTZ, CTLZ, CTPOP,

    // Select
    SELECT, 
    
    // Select with condition operator - This selects between a true value and 
    // a false value (ops #2 and #3) based on the boolean result of comparing
    // the lhs and rhs (ops #0 and #1) of a conditional expression with the 
    // condition code in op #4, a CondCodeSDNode.
    SELECT_CC,

    // SetCC operator - This evaluates to a boolean (i1) true value if the
    // condition is true.  The operands to this are the left and right operands
    // to compare (ops #0, and #1) and the condition code to compare them with
    // (op #2) as a CondCodeSDNode.
    SETCC,

    // ADD_PARTS/SUB_PARTS - These operators take two logical operands which are
    // broken into a multiple pieces each, and return the resulting pieces of
    // doing an atomic add/sub operation.  This is used to handle add/sub of
    // expanded types.  The operation ordering is:
    //       [Lo,Hi] = op [LoLHS,HiLHS], [LoRHS,HiRHS]
    ADD_PARTS, SUB_PARTS,

    // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
    // integer shift operations, just like ADD/SUB_PARTS.  The operation
    // ordering is:
    //       [Lo,Hi] = op [LoLHS,HiLHS], Amt
    SHL_PARTS, SRA_PARTS, SRL_PARTS,

    // Conversion operators.  These are all single input single output
    // operations.  For all of these, the result type must be strictly
    // wider or narrower (depending on the operation) than the source
    // type.

    // SIGN_EXTEND - Used for integer types, replicating the sign bit
    // into new bits.
    SIGN_EXTEND,

    // ZERO_EXTEND - Used for integer types, zeroing the new bits.
    ZERO_EXTEND,

    // ANY_EXTEND - Used for integer types.  The high bits are undefined.
    ANY_EXTEND,
    
    // TRUNCATE - Completely drop the high bits.
    TRUNCATE,

    // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
    // depends on the first letter) to floating point.
    SINT_TO_FP,
    UINT_TO_FP,

    // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
    // sign extend a small value in a large integer register (e.g. sign
    // extending the low 8 bits of a 32-bit register to fill the top 24 bits
    // with the 7th bit).  The size of the smaller type is indicated by the 1th
    // operand, a ValueType node.
    SIGN_EXTEND_INREG,

    // FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
    // integer.
    FP_TO_SINT,
    FP_TO_UINT,

    // FP_ROUND - Perform a rounding operation from the current
    // precision down to the specified precision (currently always 64->32).
    FP_ROUND,

    // FP_ROUND_INREG - This operator takes a floating point register, and
    // rounds it to a floating point value.  It then promotes it and returns it
    // in a register of the same size.  This operation effectively just discards
    // excess precision.  The type to round down to is specified by the 1th
    // operation, a VTSDNode (currently always 64->32->64).
    FP_ROUND_INREG,

    // FP_EXTEND - Extend a smaller FP type into a larger FP type.
    FP_EXTEND,

    // FNEG, FABS, FSQRT, FSIN, FCOS - Perform unary floating point negation,
    // absolute value, square root, sine and cosine operations.
    FNEG, FABS, FSQRT, FSIN, FCOS,

    // Other operators.  LOAD and STORE have token chains as their first
    // operand, then the same operands as an LLVM load/store instruction, then a
    // SRCVALUE node that provides alias analysis information.
    LOAD, STORE,

    // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from
    // memory and extend them to a larger value (e.g. load a byte into a word
    // register).  All three of these have four operands, a token chain, a
    // pointer to load from, a SRCVALUE for alias analysis, and a VALUETYPE node
    // indicating the type to load.
    //
    // SEXTLOAD loads the integer operand and sign extends it to a larger
    //          integer result type.
    // ZEXTLOAD loads the integer operand and zero extends it to a larger
    //          integer result type.
    // EXTLOAD  is used for two things: floating point extending loads, and
    //          integer extending loads where it doesn't matter what the high
    //          bits are set to.  The code generator is allowed to codegen this
    //          into whichever operation is more efficient.
    EXTLOAD, SEXTLOAD, ZEXTLOAD,

    // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a
    // value and stores it to memory in one operation.  This can be used for
    // either integer or floating point operands.  The first four operands of
    // this are the same as a standard store.  The fifth is the ValueType to
    // store it as (which will be smaller than the source value).
    TRUNCSTORE,

    // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
    // to a specified boundary.  The first operand is the token chain, the
    // second is the number of bytes to allocate, and the third is the alignment
    // boundary.  The size is guaranteed to be a multiple of the stack 
    // alignment, and the alignment is guaranteed to be bigger than the stack 
    // alignment (if required) or 0 to get standard stack alignment.
    DYNAMIC_STACKALLOC,

    // Control flow instructions.  These all have token chains.

    // BR - Unconditional branch.  The first operand is the chain
    // operand, the second is the MBB to branch to.
    BR,

    // BRCOND - Conditional branch.  The first operand is the chain,
    // the second is the condition, the third is the block to branch
    // to if the condition is true.
    BRCOND,

    // BRCONDTWOWAY - Two-way conditional branch.  The first operand is the
    // chain, the second is the condition, the third is the block to branch to
    // if true, and the forth is the block to branch to if false.  Targets
    // usually do not implement this, preferring to have legalize demote the
    // operation to BRCOND/BR pairs when necessary.
    BRCONDTWOWAY,

    // BR_CC - Conditional branch.  The behavior is like that of SELECT_CC, in
    // that the condition is represented as condition code, and two nodes to
    // compare, rather than as a combined SetCC node.  The operands in order are
    // chain, cc, lhs, rhs, block to branch to if condition is true.
    BR_CC,
    
    // BRTWOWAY_CC - Two-way conditional branch.  The operands in order are
    // chain, cc, lhs, rhs, block to branch to if condition is true, block to
    // branch to if condition is false.  Targets usually do not implement this,
    // preferring to have legalize demote the operation to BRCOND/BR pairs.
    BRTWOWAY_CC,
    
    // RET - Return from function.  The first operand is the chain,
    // and any subsequent operands are the return values for the
    // function.  This operation can have variable number of operands.
    RET,

    // CALL - Call to a function pointer.  The first operand is the chain, the
    // second is the destination function pointer (a GlobalAddress for a direct
    // call).  Arguments have already been lowered to explicit DAGs according to
    // the calling convention in effect here.  TAILCALL is the same as CALL, but
    // the callee is known not to access the stack of the caller.
    CALL,
    TAILCALL,

    // MEMSET/MEMCPY/MEMMOVE - The first operand is the chain, and the rest
    // correspond to the operands of the LLVM intrinsic functions.  The only
    // result is a token chain.  The alignment argument is guaranteed to be a
    // Constant node.
    MEMSET,
    MEMMOVE,
    MEMCPY,

    // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
    // a call sequence, and carry arbitrary information that target might want
    // to know.  The first operand is a chain, the rest are specified by the
    // target and not touched by the DAG optimizers.
    CALLSEQ_START,  // Beginning of a call sequence
    CALLSEQ_END,    // End of a call sequence

    // SRCVALUE - This corresponds to a Value*, and is used to associate memory
    // locations with their value.  This allows one use alias analysis
    // information in the backend.
    SRCVALUE,

    // PCMARKER - This corresponds to the pcmarker intrinsic.
    PCMARKER,

    // READPORT, WRITEPORT, READIO, WRITEIO - These correspond to the LLVM
    // intrinsics of the same name.  The first operand is a token chain, the
    // other operands match the intrinsic.  These produce a token chain in
    // addition to a value (if any).
    READPORT, WRITEPORT, READIO, WRITEIO,
    
    // HANDLENODE node - Used as a handle for various purposes.
    HANDLENODE,

    // BUILTIN_OP_END - This must be the last enum value in this list.
    BUILTIN_OP_END,
  };

  //===--------------------------------------------------------------------===//
  /// ISD::CondCode enum - These are ordered carefully to make the bitfields
  /// below work out, when considering SETFALSE (something that never exists
  /// dynamically) as 0.  "U" -> Unsigned (for integer operands) or Unordered
  /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
  /// to.  If the "N" column is 1, the result of the comparison is undefined if
  /// the input is a NAN.
  ///
  /// All of these (except for the 'always folded ops') should be handled for
  /// floating point.  For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
  /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
  ///
  /// Note that these are laid out in a specific order to allow bit-twiddling
  /// to transform conditions.
  enum CondCode {
    // Opcode          N U L G E       Intuitive operation
    SETFALSE,      //    0 0 0 0       Always false (always folded)
    SETOEQ,        //    0 0 0 1       True if ordered and equal
    SETOGT,        //    0 0 1 0       True if ordered and greater than
    SETOGE,        //    0 0 1 1       True if ordered and greater than or equal
    SETOLT,        //    0 1 0 0       True if ordered and less than
    SETOLE,        //    0 1 0 1       True if ordered and less than or equal
    SETONE,        //    0 1 1 0       True if ordered and operands are unequal
    SETO,          //    0 1 1 1       True if ordered (no nans)
    SETUO,         //    1 0 0 0       True if unordered: isnan(X) | isnan(Y)
    SETUEQ,        //    1 0 0 1       True if unordered or equal
    SETUGT,        //    1 0 1 0       True if unordered or greater than
    SETUGE,        //    1 0 1 1       True if unordered, greater than, or equal
    SETULT,        //    1 1 0 0       True if unordered or less than
    SETULE,        //    1 1 0 1       True if unordered, less than, or equal
    SETUNE,        //    1 1 1 0       True if unordered or not equal
    SETTRUE,       //    1 1 1 1       Always true (always folded)
    // Don't care operations: undefined if the input is a nan.
    SETFALSE2,     //  1 X 0 0 0       Always false (always folded)
    SETEQ,         //  1 X 0 0 1       True if equal
    SETGT,         //  1 X 0 1 0       True if greater than
    SETGE,         //  1 X 0 1 1       True if greater than or equal
    SETLT,         //  1 X 1 0 0       True if less than
    SETLE,         //  1 X 1 0 1       True if less than or equal
    SETNE,         //  1 X 1 1 0       True if not equal
    SETTRUE2,      //  1 X 1 1 1       Always true (always folded)

    SETCC_INVALID,      // Marker value.
  };

  /// isSignedIntSetCC - Return true if this is a setcc instruction that
  /// performs a signed comparison when used with integer operands.
  inline bool isSignedIntSetCC(CondCode Code) {
    return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
  }

  /// isUnsignedIntSetCC - Return true if this is a setcc instruction that
  /// performs an unsigned comparison when used with integer operands.
  inline bool isUnsignedIntSetCC(CondCode Code) {
    return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
  }

  /// isTrueWhenEqual - Return true if the specified condition returns true if
  /// the two operands to the condition are equal.  Note that if one of the two
  /// operands is a NaN, this value is meaningless.
  inline bool isTrueWhenEqual(CondCode Cond) {
    return ((int)Cond & 1) != 0;
  }

  /// getUnorderedFlavor - This function returns 0 if the condition is always
  /// false if an operand is a NaN, 1 if the condition is always true if the
  /// operand is a NaN, and 2 if the condition is undefined if the operand is a
  /// NaN.
  inline unsigned getUnorderedFlavor(CondCode Cond) {
    return ((int)Cond >> 3) & 3;
  }

  /// getSetCCInverse - Return the operation corresponding to !(X op Y), where
  /// 'op' is a valid SetCC operation.
  CondCode getSetCCInverse(CondCode Operation, bool isInteger);

  /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
  /// when given the operation for (X op Y).
  CondCode getSetCCSwappedOperands(CondCode Operation);

  /// getSetCCOrOperation - Return the result of a logical OR between different
  /// comparisons of identical values: ((X op1 Y) | (X op2 Y)).  This
  /// function returns SETCC_INVALID if it is not possible to represent the
  /// resultant comparison.
  CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);

  /// getSetCCAndOperation - Return the result of a logical AND between
  /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)).  This
  /// function returns SETCC_INVALID if it is not possible to represent the
  /// resultant comparison.
  CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
}  // end llvm::ISD namespace


//===----------------------------------------------------------------------===//
/// SDOperand - Unlike LLVM values, Selection DAG nodes may return multiple
/// values as the result of a computation.  Many nodes return multiple values,
/// from loads (which define a token and a return value) to ADDC (which returns
/// a result and a carry value), to calls (which may return an arbitrary number
/// of values).
///
/// As such, each use of a SelectionDAG computation must indicate the node that
/// computes it as well as which return value to use from that node.  This pair
/// of information is represented with the SDOperand value type.
///
class SDOperand {
public:
  SDNode *Val;        // The node defining the value we are using.
  unsigned ResNo;     // Which return value of the node we are using.

  SDOperand() : Val(0) {}
  SDOperand(SDNode *val, unsigned resno) : Val(val), ResNo(resno) {}

  bool operator==(const SDOperand &O) const {
    return Val == O.Val && ResNo == O.ResNo;
  }
  bool operator!=(const SDOperand &O) const {
    return !operator==(O);
  }
  bool operator<(const SDOperand &O) const {
    return Val < O.Val || (Val == O.Val && ResNo < O.ResNo);
  }

  SDOperand getValue(unsigned R) const {
    return SDOperand(Val, R);
  }

  /// getValueType - Return the ValueType of the referenced return value.
  ///
  inline MVT::ValueType getValueType() const;

  // Forwarding methods - These forward to the corresponding methods in SDNode.
  inline unsigned getOpcode() const;
  inline unsigned getNodeDepth() const;
  inline unsigned getNumOperands() const;
  inline const SDOperand &getOperand(unsigned i) const;
  inline bool isTargetOpcode() const;
  inline unsigned getTargetOpcode() const;

  /// hasOneUse - Return true if there is exactly one operation using this
  /// result value of the defining operator.
  inline bool hasOneUse() const;
};


/// simplify_type specializations - Allow casting operators to work directly on
/// SDOperands as if they were SDNode*'s.
template<> struct simplify_type<SDOperand> {
  typedef SDNode* SimpleType;
  static SimpleType getSimplifiedValue(const SDOperand &Val) {
    return static_cast<SimpleType>(Val.Val);
  }
};
template<> struct simplify_type<const SDOperand> {
  typedef SDNode* SimpleType;
  static SimpleType getSimplifiedValue(const SDOperand &Val) {
    return static_cast<SimpleType>(Val.Val);
  }
};


/// SDNode - Represents one node in the SelectionDAG.
///
class SDNode {
  /// NodeType - The operation that this node performs.
  ///
  unsigned short NodeType;

  /// NodeDepth - Node depth is defined as MAX(Node depth of children)+1.  This
  /// means that leaves have a depth of 1, things that use only leaves have a
  /// depth of 2, etc.
  unsigned short NodeDepth;

  /// Operands - The values that are used by this operation.
  ///
  std::vector<SDOperand> Operands;

  /// Values - The types of the values this node defines.  SDNode's may define
  /// multiple values simultaneously.
  std::vector<MVT::ValueType> Values;

  /// Uses - These are all of the SDNode's that use a value produced by this
  /// node.
  std::vector<SDNode*> Uses;
public:

  //===--------------------------------------------------------------------===//
  //  Accessors
  //
  unsigned getOpcode()  const { return NodeType; }
  bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
  unsigned getTargetOpcode() const {
    assert(isTargetOpcode() && "Not a target opcode!");
    return NodeType - ISD::BUILTIN_OP_END;
  }

  size_t use_size() const { return Uses.size(); }
  bool use_empty() const { return Uses.empty(); }
  bool hasOneUse() const { return Uses.size() == 1; }

  /// getNodeDepth - Return the distance from this node to the leaves in the
  /// graph.  The leaves have a depth of 1.
  unsigned getNodeDepth() const { return NodeDepth; }

  typedef std::vector<SDNode*>::const_iterator use_iterator;
  use_iterator use_begin() const { return Uses.begin(); }
  use_iterator use_end() const { return Uses.end(); }

  /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
  /// indicated value.  This method ignores uses of other values defined by this
  /// operation.
  bool hasNUsesOfValue(unsigned NUses, unsigned Value);

  /// getNumOperands - Return the number of values used by this operation.
  ///
  unsigned getNumOperands() const { return Operands.size(); }

  const SDOperand &getOperand(unsigned Num) {
    assert(Num < Operands.size() && "Invalid child # of SDNode!");
    return Operands[Num];
  }

  const SDOperand &getOperand(unsigned Num) const {
    assert(Num < Operands.size() && "Invalid child # of SDNode!");
    return Operands[Num];
  }
  typedef std::vector<SDOperand>::const_iterator op_iterator;
  op_iterator op_begin() const { return Operands.begin(); }
  op_iterator op_end() const { return Operands.end(); }


  /// getNumValues - Return the number of values defined/returned by this
  /// operator.
  ///
  unsigned getNumValues() const { return Values.size(); }

  /// getValueType - Return the type of a specified result.
  ///
  MVT::ValueType getValueType(unsigned ResNo) const {
    assert(ResNo < Values.size() && "Illegal result number!");
    return Values[ResNo];
  }

  typedef std::vector<MVT::ValueType>::const_iterator value_iterator;
  value_iterator value_begin() const { return Values.begin(); }
  value_iterator value_end() const { return Values.end(); }

  /// getOperationName - Return the opcode of this operation for printing.
  ///
  const char* getOperationName(const SelectionDAG *G = 0) const;
  void dump() const;
  void dump(const SelectionDAG *G) const;

  static bool classof(const SDNode *) { return true; }


  /// setAdjCallChain - This method should only be used by the legalizer.
  void setAdjCallChain(SDOperand N);

protected:
  friend class SelectionDAG;

  SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT), NodeDepth(1) {
    Values.reserve(1);
    Values.push_back(VT);
  }
  SDNode(unsigned NT, SDOperand Op)
    : NodeType(NT), NodeDepth(Op.Val->getNodeDepth()+1) {
    Operands.reserve(1); Operands.push_back(Op);
    Op.Val->Uses.push_back(this);
  }
  SDNode(unsigned NT, SDOperand N1, SDOperand N2)
    : NodeType(NT) {
    if (N1.Val->getNodeDepth() > N2.Val->getNodeDepth())
      NodeDepth = N1.Val->getNodeDepth()+1;
    else
      NodeDepth = N2.Val->getNodeDepth()+1;
    Operands.reserve(2); Operands.push_back(N1); Operands.push_back(N2);
    N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
  }
  SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3)
    : NodeType(NT) {
    unsigned ND = N1.Val->getNodeDepth();
    if (ND < N2.Val->getNodeDepth())
      ND = N2.Val->getNodeDepth();
    if (ND < N3.Val->getNodeDepth())
      ND = N3.Val->getNodeDepth();
    NodeDepth = ND+1;

    Operands.reserve(3); Operands.push_back(N1); Operands.push_back(N2);
    Operands.push_back(N3);
    N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
    N3.Val->Uses.push_back(this);
  }
  SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4)
    : NodeType(NT) {
    unsigned ND = N1.Val->getNodeDepth();
    if (ND < N2.Val->getNodeDepth())
      ND = N2.Val->getNodeDepth();
    if (ND < N3.Val->getNodeDepth())
      ND = N3.Val->getNodeDepth();
    if (ND < N4.Val->getNodeDepth())
      ND = N4.Val->getNodeDepth();
    NodeDepth = ND+1;

    Operands.reserve(4); Operands.push_back(N1); Operands.push_back(N2);
    Operands.push_back(N3); Operands.push_back(N4);
    N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
    N3.Val->Uses.push_back(this); N4.Val->Uses.push_back(this);
  }
  SDNode(unsigned NT, std::vector<SDOperand> &Nodes) : NodeType(NT) {
    Operands.swap(Nodes);
    unsigned ND = 0;
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      Operands[i].Val->Uses.push_back(this);
      if (ND < Operands[i].Val->getNodeDepth())
        ND = Operands[i].Val->getNodeDepth();
    }
    NodeDepth = ND+1;
  }

  virtual ~SDNode() {}

  /// MorphNodeTo - This clears the return value and operands list, and sets the
  /// opcode of the node to the specified value.  This should only be used by
  /// the SelectionDAG class.
  void MorphNodeTo(unsigned Opc) {
    NodeType = Opc;
    Values.clear();
    
    // Clear the operands list, updating used nodes to remove this from their
    // use list.
    while (!Operands.empty()) {
      SDNode *O = Operands.back().Val;
      Operands.pop_back();
      O->removeUser(this);
    }
  }
  
  void setValueTypes(MVT::ValueType VT) {
    Values.reserve(1);
    Values.push_back(VT);
  }
  void setValueTypes(MVT::ValueType VT1, MVT::ValueType VT2) {
    Values.reserve(2);
    Values.push_back(VT1);
    Values.push_back(VT2);
  }
  /// Note: this method destroys the vector passed in.
  void setValueTypes(std::vector<MVT::ValueType> &VTs) {
    std::swap(Values, VTs);
  }
  
  void setOperands(SDOperand Op0) {
    Operands.reserve(1);
    Operands.push_back(Op0);
    Op0.Val->Uses.push_back(this);
  }
  void setOperands(SDOperand Op0, SDOperand Op1) {
    Operands.reserve(2);
    Operands.push_back(Op0);
    Operands.push_back(Op1);
    Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
  }
  void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2) {
    Operands.reserve(3);
    Operands.push_back(Op0);
    Operands.push_back(Op1);
    Operands.push_back(Op2);
    Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
    Op2.Val->Uses.push_back(this);
  }
  void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3) {
    Operands.reserve(4);
    Operands.push_back(Op0);
    Operands.push_back(Op1);
    Operands.push_back(Op2);
    Operands.push_back(Op3);
    Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
    Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
  }
  void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3,
                   SDOperand Op4) {
    Operands.reserve(5);
    Operands.push_back(Op0);
    Operands.push_back(Op1);
    Operands.push_back(Op2);
    Operands.push_back(Op3);
    Operands.push_back(Op4);
    Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
    Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
    Op4.Val->Uses.push_back(this);
  }
  void addUser(SDNode *User) {
    Uses.push_back(User);
  }
  void removeUser(SDNode *User) {
    // Remove this user from the operand's use list.
    for (unsigned i = Uses.size(); ; --i) {
      assert(i != 0 && "Didn't find user!");
      if (Uses[i-1] == User) {
        Uses[i-1] = Uses.back();
        Uses.pop_back();
        return;
      }
    }
  }
};


// Define inline functions from the SDOperand class.

inline unsigned SDOperand::getOpcode() const {
  return Val->getOpcode();
}
inline unsigned SDOperand::getNodeDepth() const {
  return Val->getNodeDepth();
}
inline MVT::ValueType SDOperand::getValueType() const {
  return Val->getValueType(ResNo);
}
inline unsigned SDOperand::getNumOperands() const {
  return Val->getNumOperands();
}
inline const SDOperand &SDOperand::getOperand(unsigned i) const {
  return Val->getOperand(i);
}
inline bool SDOperand::isTargetOpcode() const {
  return Val->isTargetOpcode();
}
inline unsigned SDOperand::getTargetOpcode() const {
  return Val->getTargetOpcode();
}
inline bool SDOperand::hasOneUse() const {
  return Val->hasNUsesOfValue(1, ResNo);
}

/// HandleSDNode - This class is used to form a handle around another node that
/// is persistant and is updated across invocations of replaceAllUsesWith on its
/// operand.  This node should be directly created by end-users and not added to
/// the AllNodes list.
class HandleSDNode : public SDNode {
public:
  HandleSDNode(SDOperand X) : SDNode(ISD::HANDLENODE, X) {}
  ~HandleSDNode() {
    MorphNodeTo(ISD::HANDLENODE);  // Drops operand uses.
  }
  
  SDOperand getValue() const { return getOperand(0); }
};


class ConstantSDNode : public SDNode {
  uint64_t Value;
protected:
  friend class SelectionDAG;
  ConstantSDNode(bool isTarget, uint64_t val, MVT::ValueType VT)
    : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, VT), Value(val) {
  }
public:

  uint64_t getValue() const { return Value; }

  int64_t getSignExtended() const {
    unsigned Bits = MVT::getSizeInBits(getValueType(0));
    return ((int64_t)Value << (64-Bits)) >> (64-Bits);
  }

  bool isNullValue() const { return Value == 0; }
  bool isAllOnesValue() const {
    int NumBits = MVT::getSizeInBits(getValueType(0));
    if (NumBits == 64) return Value+1 == 0;
    return Value == (1ULL << NumBits)-1;
  }

  static bool classof(const ConstantSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::Constant ||
           N->getOpcode() == ISD::TargetConstant;
  }
};

class ConstantFPSDNode : public SDNode {
  double Value;
protected:
  friend class SelectionDAG;
  ConstantFPSDNode(double val, MVT::ValueType VT)
    : SDNode(ISD::ConstantFP, VT), Value(val) {
  }
public:

  double getValue() const { return Value; }

  /// isExactlyValue - We don't rely on operator== working on double values, as
  /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
  /// As such, this method can be used to do an exact bit-for-bit comparison of
  /// two floating point values.
  bool isExactlyValue(double V) const;

  static bool classof(const ConstantFPSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::ConstantFP;
  }
};

class GlobalAddressSDNode : public SDNode {
  GlobalValue *TheGlobal;
protected:
  friend class SelectionDAG;
  GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT)
    : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress, VT) {
    TheGlobal = const_cast<GlobalValue*>(GA);
  }
public:

  GlobalValue *getGlobal() const { return TheGlobal; }

  static bool classof(const GlobalAddressSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::GlobalAddress ||
           N->getOpcode() == ISD::TargetGlobalAddress;
  }
};


class FrameIndexSDNode : public SDNode {
  int FI;
protected:
  friend class SelectionDAG;
  FrameIndexSDNode(int fi, MVT::ValueType VT, bool isTarg)
    : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, VT), FI(fi) {}
public:

  int getIndex() const { return FI; }

  static bool classof(const FrameIndexSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::FrameIndex ||
           N->getOpcode() == ISD::TargetFrameIndex;
  }
};

class ConstantPoolSDNode : public SDNode {
  Constant *C;
protected:
  friend class SelectionDAG;
  ConstantPoolSDNode(Constant *c, MVT::ValueType VT, bool isTarget)
    : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT),
    C(c) {}
public:

  Constant *get() const { return C; }

  static bool classof(const ConstantPoolSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::ConstantPool ||
           N->getOpcode() == ISD::TargetConstantPool;
  }
};

class BasicBlockSDNode : public SDNode {
  MachineBasicBlock *MBB;
protected:
  friend class SelectionDAG;
  BasicBlockSDNode(MachineBasicBlock *mbb)
    : SDNode(ISD::BasicBlock, MVT::Other), MBB(mbb) {}
public:

  MachineBasicBlock *getBasicBlock() const { return MBB; }

  static bool classof(const BasicBlockSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::BasicBlock;
  }
};

class SrcValueSDNode : public SDNode {
  const Value *V;
  int offset;
protected:
  friend class SelectionDAG;
  SrcValueSDNode(const Value* v, int o)
    : SDNode(ISD::SRCVALUE, MVT::Other), V(v), offset(o) {}

public:
  const Value *getValue() const { return V; }
  int getOffset() const { return offset; }

  static bool classof(const SrcValueSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::SRCVALUE;
  }
};


class RegisterSDNode : public SDNode {
  unsigned Reg;
protected:
  friend class SelectionDAG;
  RegisterSDNode(unsigned reg, MVT::ValueType VT)
    : SDNode(ISD::Register, VT), Reg(reg) {}
public:

  unsigned getReg() const { return Reg; }

  static bool classof(const RegisterSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::Register;
  }
};

class ExternalSymbolSDNode : public SDNode {
  const char *Symbol;
protected:
  friend class SelectionDAG;
  ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT::ValueType VT)
    : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, VT),
      Symbol(Sym) {
    }
public:

  const char *getSymbol() const { return Symbol; }

  static bool classof(const ExternalSymbolSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::ExternalSymbol ||
           N->getOpcode() == ISD::TargetExternalSymbol;
  }
};

class CondCodeSDNode : public SDNode {
  ISD::CondCode Condition;
protected:
  friend class SelectionDAG;
  CondCodeSDNode(ISD::CondCode Cond)
    : SDNode(ISD::CONDCODE, MVT::Other), Condition(Cond) {
  }
public:

  ISD::CondCode get() const { return Condition; }

  static bool classof(const CondCodeSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::CONDCODE;
  }
};

/// VTSDNode - This class is used to represent MVT::ValueType's, which are used
/// to parameterize some operations.
class VTSDNode : public SDNode {
  MVT::ValueType ValueType;
protected:
  friend class SelectionDAG;
  VTSDNode(MVT::ValueType VT)
    : SDNode(ISD::VALUETYPE, MVT::Other), ValueType(VT) {}
public:

  MVT::ValueType getVT() const { return ValueType; }

  static bool classof(const VTSDNode *) { return true; }
  static bool classof(const SDNode *N) {
    return N->getOpcode() == ISD::VALUETYPE;
  }
};


class SDNodeIterator : public forward_iterator<SDNode, ptrdiff_t> {
  SDNode *Node;
  unsigned Operand;

  SDNodeIterator(SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
public:
  bool operator==(const SDNodeIterator& x) const {
    return Operand == x.Operand;
  }
  bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }

  const SDNodeIterator &operator=(const SDNodeIterator &I) {
    assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
    Operand = I.Operand;
    return *this;
  }

  pointer operator*() const {
    return Node->getOperand(Operand).Val;
  }
  pointer operator->() const { return operator*(); }

  SDNodeIterator& operator++() {                // Preincrement
    ++Operand;
    return *this;
  }
  SDNodeIterator operator++(int) { // Postincrement
    SDNodeIterator tmp = *this; ++*this; return tmp;
  }

  static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); }
  static SDNodeIterator end  (SDNode *N) {
    return SDNodeIterator(N, N->getNumOperands());
  }

  unsigned getOperand() const { return Operand; }
  const SDNode *getNode() const { return Node; }
};

template <> struct GraphTraits<SDNode*> {
  typedef SDNode NodeType;
  typedef SDNodeIterator ChildIteratorType;
  static inline NodeType *getEntryNode(SDNode *N) { return N; }
  static inline ChildIteratorType child_begin(NodeType *N) {
    return SDNodeIterator::begin(N);
  }
  static inline ChildIteratorType child_end(NodeType *N) {
    return SDNodeIterator::end(N);
  }
};

} // end llvm namespace

#endif